मल्टी-लेबल क्लासिफायर पर स्किट-लर्न के क्रॉस सत्यापन कार्यों का उपयोग कैसे करें


20

मैं एक डेटा सेट पर अलग-अलग क्लासीफायर का परीक्षण कर रहा हूं, जहां 5 कक्षाएं हैं और प्रत्येक उदाहरण इन वर्गों में से एक या अधिक से संबंधित हो सकता है, इसलिए मैं विशेष रूप से स्किकिट-लर्न के मल्टी-लेबल क्लासिफायर का उपयोग कर रहा हूं 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-0.12 सीख रहा हूं। मेरा डेटा दो सरणियों (एक्स और वाई) के रूप में है, जिनकी आकृतियाँ (98816, 4) और (98816, 5) हैं, अर्थात प्रति उदाहरण 4 सुविधाएँ और 5 वर्ग लेबल। लेबल या तो उस कक्षा के भीतर इंगित सदस्यता के लिए 1 या 0 हैं। क्या मैं सही प्रारूप का उपयोग कर रहा हूं क्योंकि मुझे इसके बारे में अधिक दस्तावेज नहीं दिख रहे हैं?

जवाबों:


10

स्तरीकृत नमूनाकरण का मतलब है कि वर्ग सदस्यता वितरण आपके KFold नमूने में संरक्षित है। यह मल्टीलेबल मामले में बहुत मायने नहीं रखता है जहाँ आपके लक्ष्य वेक्टर का प्रति अवलोकन एक से अधिक लेबल हो सकता है।

इस अर्थ में स्तरीकृत की दो संभावित व्याख्याएँ हैं।

के लिए लेबल जहां उनमें से कम से कम एक भर जाता है देता है कि आप अद्वितीय लेबल। आप प्रत्येक अद्वितीय लेबल डिब्बे पर स्तरीकृत नमूनाकरण कर सकते हैं।n i = 1 2 nnΣमैं=1n2n

अन्य विकल्प यह है कि प्रशिक्षण डेटा सेंट की कोशिश करें और खंड करें कि लेबल वैक्टर के वितरण की संभाव्यता द्रव्यमान सिलवटों पर लगभग समान है। उदाहरण के लिए

import numpy as np

np.random.seed(1)
y = np.random.randint(0, 2, (5000, 5))
y = y[np.where(y.sum(axis=1) != 0)[0]]


def proba_mass_split(y, folds=7):
    obs, classes = y.shape
    dist = y.sum(axis=0).astype('float')
    dist /= dist.sum()
    index_list = []
    fold_dist = np.zeros((folds, classes), dtype='float')
    for _ in xrange(folds):
        index_list.append([])
    for i in xrange(obs):
        if i < folds:
            target_fold = i
        else:
            normed_folds = fold_dist.T / fold_dist.sum(axis=1)
            how_off = normed_folds.T - dist
            target_fold = np.argmin(np.dot((y[i] - .5).reshape(1, -1), how_off.T))
        fold_dist[target_fold] += y[i]
        index_list[target_fold].append(i)
    print("Fold distributions are")
    print(fold_dist)
    return index_list

if __name__ == '__main__':
    proba_mass_split(y)

सामान्य प्रशिक्षण प्राप्त करने के लिए, KFold का उत्पादन करने वाले सूचकांकों का परीक्षण करते हुए आप इसे फिर से लिखना चाहते हैं कि यह प्रत्येक सूचकांक के np.setdiff1d को np.arange (y.shape [0]) के साथ लौटाता है, फिर इसे एक इटेर विधि के साथ वर्ग में लपेटें ।


इस स्पष्टीकरण के लिए धन्यवाद। मैं सिर्फ कुछ जांचना चाहूंगा, क्या OneVsRestClassifierएक 2D सरणी (जैसे yआपके उदाहरण कोड में) या क्लास लेबल की सूचियों का एक हिस्सा स्वीकार करता है ? मैं पूछता हूं क्योंकि मैंने अभी-अभी शिक-सीख पर मल्टी-लेबल वर्गीकरण उदाहरण को देखा और देखा कि make_multilabel_classificationफ़ंक्शन ([2], [0], [0, 2], [0]...)3 वर्गों का उपयोग करते समय , क्लास लेबल की सूचियों की एक टुकड़ी लौटाता है ?
जिप

2
यह दोनों तरह से काम करता है। जब टुपल्स की एक सूची पारित की जाती है तो यह एक sklearn.preprocessing.LabelBinarizer को फिट बैठता है। आप जानते हैं कि कुछ एल्गोरिदम मल्टीस्केल्स मल्टीलेबल केस में काम करते हैं। विशेष रूप से यादृच्छिक।
जेसिका मिक

बहुत बहुत धन्यवाद, यह कम से कम मुझे दुर्घटनाओं से अतीत मिला। फिलहाल मैंने K- गुना क्रॉस सत्यापन पर स्विच किया है, लेकिन मुझे लगता है कि मैं जल्द ही आपके कोड का उपयोग करूंगा। हालांकि, cross_val_score द्वारा लौटाए गए स्कोर में केवल दो कॉलम हैं, जैसे कि केवल दो वर्ग हैं। metrics.confusion_matrix2x2 भ्रम पैदा करने वाले मेट्रिसेस को बदलना । क्या कोई भी मैट्रिक्स मल्टी-लेबल क्लासिफायर का समर्थन करता है?
जिप

मैंने अपने स्वयं के उप-प्रश्न का उत्तर दिया है। मल्टी-लेबल क्लासिफायर का समर्थन करने वाले मैट्रिक्स केवल scikit-0.14-rc में दिखाई देते हैं, इसलिए मुझे उस क्षमता को अपग्रेड करना होगा, या मुझे स्वयं करना होगा। मदद और कोड के लिए धन्यवाद।
जिप

मैंने रिटर्न स्टेटमेंट पर सरणी को हटा दिया। ऐसा कोई कारण नहीं है कि आप हमेशा डेटा बिंदुओं का एक पूरी तरह से विभाजित सेट पाएंगे। मुझे पता है अगर यह काम करता है। आपको अपने कोड में कुछ परीक्षण भी लिखना चाहिए। मैं पूरे दिन उत्तल अनुकूलन एल्गोरिदम को घूरने के बाद इस एल्गोरिथ्म की तरह सांस लेता हूं।
जेसिका मिक

3

आप जाँच कर सकते हैं: मल्टी-लेबल डेटा के स्तरीकरण पर

यहाँ लेखक पहले अनूठे लेबलसेट से नमूना लेने का सरल विचार बताते हैं और फिर मल्टी-लेबल चिपसेट के लिए एक नया दृष्टिकोण पुनरावृत्ति स्तरीकरण शुरू करते हैं ।

पुनरावृत्ति स्तरीकरण का दृष्टिकोण लालची है।

एक त्वरित अवलोकन के लिए, यहाँ पुनरावृत्ति स्तरीकरण है:

पहले उन्हें पता चलता है कि प्रत्येक के-फोल्ड में कितने उदाहरण होने चाहिए।

  • मैंजेसीमैंजे

  • एलडीएल

  • डीएलसीजेएलएल

  • सी

मुख्य विचार पहले उन लेबलों पर ध्यान केंद्रित करना है जो दुर्लभ हैं, यह विचार उस परिकल्पना से आता है

"यदि दुर्लभ लेबल की प्राथमिकता में जांच नहीं की जाती है, तो उन्हें अवांछित तरीके से वितरित किया जा सकता है, और इसके बाद मरम्मत नहीं की जा सकती है"

यह समझने के लिए कि संबंध कैसे टूटे हैं और अन्य विवरण, मैं पेपर पढ़ने की सलाह दूंगा। इसके अलावा, प्रयोगों अनुभाग से जो मैं समझ सकता हूं, लेबलसेट / उदाहरणों के अनुपात के आधार पर कोई व्यक्ति अद्वितीय लेबलसेट आधारित या इस प्रस्तावित पुनरावृत्ति स्तरीकरण विधि का उपयोग करना चाह सकता है। इस अनुपात के निचले मूल्यों के लिए, सिलवटों के पार लेबल का वितरण पुनरावृत्ति स्तरीकरण के रूप में कुछ मामलों में करीब या बेहतर है। इस अनुपात के उच्च मूल्यों के लिए, पुनरावृति स्तरीकरण को सिलवटों में बेहतर वितरण बनाए रखने के लिए दिखाया गया है।


1
उल्लिखित पेपर की पीडीएफ से लिंक: lpis.csd.auth.gr/publications/sechidis-ecmlpkdd-2011.pdf
17:51
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.