Saya menguji berbagai pengklasifikasi pada kumpulan data di mana terdapat 5 kelas dan setiap instance dapat menjadi milik satu atau lebih dari kelas-kelas ini, jadi saya menggunakan pengklasifikasi multi-label scikit-learn, khususnya sklearn.multiclass.OneVsRestClassifier
. Sekarang saya ingin melakukan validasi silang menggunakan sklearn.cross_validation.StratifiedKFold
. Ini menghasilkan kesalahan berikut:
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
Perhatikan bahwa melatih pengelompokan multi-label tidak macet, tetapi validasi silang tidak. Bagaimana saya harus melakukan validasi silang untuk pengelompokan multi-label ini?
Saya juga telah menulis versi kedua yang memecah masalah menjadi pelatihan dan memvalidasi silang 5 pengklasifikasi yang terpisah. Ini berfungsi dengan baik.
Ini kode saya. Fungsinya test_classifier_multilabel
adalah yang memberi masalah. test_classifier
adalah usaha saya yang lain (memecah masalah menjadi 5 pengklasifikasi dan 5 cross-validations).
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()
Saya menggunakan Ubuntu 13.04 dan scikit-belajar 0.12. Data saya dalam bentuk dua array (X dan Y) yang memiliki bentuk (98816, 4) dan (98816, 5), yaitu 4 fitur per instance dan 5 label kelas. Labelnya adalah 1 atau 0 untuk mengindikasikan keanggotaan dalam kelas itu. Apakah saya menggunakan format yang benar karena saya tidak melihat banyak dokumentasi tentang itu?
OneVsRestClassifier
menerima array 2D (misalnyay
dalam kode contoh Anda) atau tupel daftar label kelas? Saya bertanya karena saya melihat contoh klasifikasi multi-label pada scikit-learn tadi dan melihat bahwamake_multilabel_classification
fungsinya mengembalikan tupel daftar label kelas, misalnya([2], [0], [0, 2], [0]...)
ketika menggunakan 3 kelas?metrics.confusion_matrix
menghasilkan matriks kebingungan 2x2. Apakah ada metrik yang mendukung pengklasifikasi multi-label?Anda mungkin ingin memeriksa: Pada stratifikasi data multi-label .
Di sini penulis pertama kali menceritakan ide sederhana pengambilan sampel dari label unik dan kemudian memperkenalkan pendekatan baru stratifikasi iteratif untuk dataset multi-label.
Pendekatan stratifikasi iteratif serakah.
Untuk tinjauan singkat, inilah yang dilakukan oleh stratifikasi iteratif:
Pertama, mereka mencari tahu berapa banyak contoh yang harus dimasukkan ke dalam masing-masing lipatan k.
Gagasan utamanya adalah pertama-tama fokus pada label-label yang langka, ide ini berasal dari hipotesis itu
Untuk memahami bagaimana ikatan rusak dan detail lainnya, saya akan merekomendasikan membaca koran. Juga, dari bagian percobaan apa yang dapat saya pahami adalah, tergantung pada labelset / contoh rasio seseorang mungkin ingin menggunakan labelset unik atau metode stratifikasi iteratif yang diusulkan ini. Untuk nilai yang lebih rendah dari rasio ini, distribusi label pada lipatan dekat atau lebih baik dalam beberapa kasus sebagai stratifikasi berulang. Untuk nilai yang lebih tinggi dari rasio ini, stratifikasi iteratif terbukti mempertahankan distribusi yang lebih baik di lipatan.
sumber