ผมทดสอบลักษณนามแตกต่างกันในชุดข้อมูลที่มี 5 ชั้นเรียนและเช่นกันสามารถอยู่ในหนึ่งหรือมากกว่าหนึ่งของการเรียนเหล่านี้ดังนั้นฉันใช้ scikit sklearn.multiclass.OneVsRestClassifier
การเรียนรู้ของลักษณนามหลายป้ายโดยเฉพาะ sklearn.cross_validation.StratifiedKFold
ตอนนี้ผมต้องการที่จะดำเนินการตรวจสอบข้ามใช้ สิ่งนี้ทำให้เกิดข้อผิดพลาดดังต่อไปนี้:
Traceback (most recent call last):
File "mlfromcsv.py", line 93, in <module>
main()
File "mlfromcsv.py", line 77, in main
test_classifier_multilabel(svm.LinearSVC(), X, Y, 'Linear Support Vector Machine')
File "mlfromcsv.py", line 44, in test_classifier_multilabel
scores = cross_validation.cross_val_score(clf_ml, X, Y_list, cv=cv, score_func=metrics.precision_recall_fscore_support, n_jobs=jobs)
File "/usr/lib/pymodules/python2.7/sklearn/cross_validation.py", line 1046, in cross_val_score
X, y = check_arrays(X, y, sparse_format='csr')
File "/usr/lib/pymodules/python2.7/sklearn/utils/validation.py", line 144, in check_arrays
size, n_samples))
ValueError: Found array with dim 5. Expected 98816
โปรดทราบว่าการฝึกอบรมตัวจําแนกฉลากหลายป้ายนั้นไม่ผิดพลาด แต่การตรวจสอบข้าม ฉันจะต้องทำการตรวจสอบข้ามสำหรับตัวแยกประเภทหลายฉลากนี้ได้อย่างไร
ฉันยังได้เขียนเวอร์ชันที่สองที่แยกแยะปัญหาในการฝึกอบรมและการตรวจสอบความถูกต้องของตัวแยกประเภท 5 ตัว มันใช้งานได้ดี
นี่คือรหัสของฉัน ฟังก์ชั่นtest_classifier_multilabel
เป็นสิ่งที่ทำให้เกิดปัญหา test_classifier
คือความพยายามอื่นของฉัน (การแบ่งปัญหาออกเป็น 5 ตัวแยกประเภทและ 5 การตรวจสอบความถูกต้องข้าม)
import numpy as np
from sklearn import *
from sklearn.multiclass import OneVsRestClassifier
from sklearn.neighbors import KNeighborsClassifier
import time
def test_classifier(clf, X, Y, description, jobs=1):
print '=== Testing classifier {0} ==='.format(description)
for class_idx in xrange(Y.shape[1]):
print ' > Cross-validating for class {:d}'.format(class_idx)
n_samples = X.shape[0]
cv = cross_validation.StratifiedKFold(Y[:,class_idx], 3)
t_start = time.clock()
scores = cross_validation.cross_val_score(clf, X, Y[:,class_idx], cv=cv, score_func=metrics.precision_recall_fscore_support, n_jobs=jobs)
t_end = time.clock();
print 'Cross validation time: {:0.3f}s.'.format(t_end-t_start)
str_tbl_fmt = '{:>15s}{:>15s}{:>15s}{:>15s}{:>15s}'
str_tbl_entry_fmt = '{:0.2f} +/- {:0.2f}'
print str_tbl_fmt.format('', 'Precision', 'Recall', 'F1 score', 'Support')
for (score_class, lbl) in [(0, 'Negative'), (1, 'Positive')]:
mean_precision = scores[:,0,score_class].mean()
std_precision = scores[:,0,score_class].std()
mean_recall = scores[:,1,score_class].mean()
std_recall = scores[:,1,score_class].std()
mean_f1_score = scores[:,2,score_class].mean()
std_f1_score = scores[:,2,score_class].std()
support = scores[:,3,score_class].mean()
print str_tbl_fmt.format(
lbl,
str_tbl_entry_fmt.format(mean_precision, std_precision),
str_tbl_entry_fmt.format(mean_recall, std_recall),
str_tbl_entry_fmt.format(mean_f1_score, std_f1_score),
'{:0.2f}'.format(support))
def test_classifier_multilabel(clf, X, Y, description, jobs=1):
print '=== Testing multi-label classifier {0} ==='.format(description)
n_samples = X.shape[0]
Y_list = [value for value in Y.T]
print 'Y_list[0].shape:', Y_list[0].shape, 'len(Y_list):', len(Y_list)
cv = cross_validation.StratifiedKFold(Y_list, 3)
clf_ml = OneVsRestClassifier(clf)
accuracy = (clf_ml.fit(X, Y).predict(X) != Y).sum()
print 'Accuracy: {:0.2f}'.format(accuracy)
scores = cross_validation.cross_val_score(clf_ml, X, Y_list, cv=cv, score_func=metrics.precision_recall_fscore_support, n_jobs=jobs)
str_tbl_fmt = '{:>15s}{:>15s}{:>15s}{:>15s}{:>15s}'
str_tbl_entry_fmt = '{:0.2f} +/- {:0.2f}'
print str_tbl_fmt.format('', 'Precision', 'Recall', 'F1 score', 'Support')
for (score_class, lbl) in [(0, 'Negative'), (1, 'Positive')]:
mean_precision = scores[:,0,score_class].mean()
std_precision = scores[:,0,score_class].std()
mean_recall = scores[:,1,score_class].mean()
std_recall = scores[:,1,score_class].std()
mean_f1_score = scores[:,2,score_class].mean()
std_f1_score = scores[:,2,score_class].std()
support = scores[:,3,score_class].mean()
print str_tbl_fmt.format(
lbl,
str_tbl_entry_fmt.format(mean_precision, std_precision),
str_tbl_entry_fmt.format(mean_recall, std_recall),
str_tbl_entry_fmt.format(mean_f1_score, std_f1_score),
'{:0.2f}'.format(support))
def main():
nfeatures = 13
nclasses = 5
ncolumns = nfeatures + nclasses
data = np.loadtxt('./feature_db.csv', delimiter=',', usecols=range(ncolumns))
print data, data.shape
X = np.hstack((data[:,0:3], data[:,(nfeatures-1):nfeatures]))
print 'X.shape:', X.shape
Y = data[:,nfeatures:ncolumns]
print 'Y.shape:', Y.shape
test_classifier(svm.LinearSVC(), X, Y, 'Linear Support Vector Machine', jobs=-1)
test_classifier_multilabel(svm.LinearSVC(), X, Y, 'Linear Support Vector Machine')
if __name__ =='__main__':
main()
ฉันใช้ Ubuntu 13.04 และ scikit-learn 0.12 ข้อมูลของฉันอยู่ในรูปแบบของสองอาร์เรย์ (X และ Y) ที่มีรูปร่าง (98816, 4) และ (98816, 5) เช่น 4 คุณสมบัติต่ออินสแตนซ์และ 5 คลาสฉลาก เลเบลเป็น 1 หรือ 0 เพื่อระบุความเป็นสมาชิกภายในคลาสนั้น ฉันใช้รูปแบบที่ถูกต้องเนื่องจากฉันไม่เห็นเอกสารมากมายเกี่ยวกับสิ่งนั้นหรือไม่
OneVsRestClassifier
รับอาร์เรย์ 2 มิติ (เช่นy
ในโค้ดตัวอย่างของคุณ) หรือ tuple ของรายการของป้ายชื่อชั้นเรียนหรือไม่ ฉันถามเพราะฉันดูตัวอย่างการจัดหมวดหมู่หลายฉลากบน scikit- เรียนรู้เมื่อเร็ว ๆ นี้และเห็นว่าmake_multilabel_classification
ฟังก์ชั่นคืนค่า tuple ของรายการของป้ายชื่อชั้นเรียนเช่น([2], [0], [0, 2], [0]...)
เมื่อใช้ 3 ชั้น?