5

ich mit Multi-Label-Klassifizierung mit OneVsRestClassifier und SVC,Sklearn: Beurteilen Sie die Leistung eines jeden Klassifikator von OneVsRestClassifier innerhalb GridSearchCV

from sklearn.datasets import make_multilabel_classification 
from sklearn.multiclass import OneVsRestClassifier 
from sklearn.svm import SVC 
from sklearn.grid_search import GridSearchCV 

L=3 
X, y = make_multilabel_classification(n_classes=L, n_labels=2, 
            allow_unlabeled=True, 
            random_state=1, return_indicator=True)  
model_to_set = OneVsRestClassifier(SVC()) 

parameters = { 
    "estimator__C": [1,2,4,8], 
    "estimator__kernel": ["poly","rbf"], 
    "estimator__degree":[1, 2, 3, 4], 
} 

model_tunning = GridSearchCV(model_to_set, param_grid=parameters, 
          scoring='f1') 

model_tunning.fit(X, y) 

print model_tunning.best_score_ 
print model_tunning.best_params_ 

#0.855175822314 
#{'estimator__kernel': 'poly', 'estimator__C': 1, 'estimator__degree': 3} 

erste Frage

behandle Was ist die Zahl 0.85 darstellt für? Ist es das beste Ergebnis unter den L Klassifikatoren oder dem gemittelten? Entspricht die Menge der Parameter den besten Scorern unter L Klassifikatoren?

2. Frage

Basierend auf der Tatsache, dass, wenn ich Recht habe, die OneVsRestClassifier buchstäblich L Klassifizierer für jedes Label baut, kann man erwarten, dass die Leistung von jedem Etikett zuzugreifen oder zu beobachten. Aber wie, in dem obigen Beispiel, um L Punkte aus dem GridSearchCV Objekt zu erhalten?

EDIT

das Problem zu vereinfachen und ich mehr über OneVsRestClassifier helfen zu verstehen, bevor Tuning-Modell,

model_to_set.fit(X,y) 
gp = model_to_set.predict(X) # the "global" prediction 
fp = model_to_set.estimators_[0].predict(X) # the first-class prediction 
sp = model_to_set.estimators_[1].predict(X) # the second-class prediction 
tp = model_to_set.estimators_[2].predict(X) # the third-class prediction 

Es kann, dass gp.T[0]==fp, gp.T[1]==sp und gp.T[2]==tp gezeigt werden. Also ist die "globale" Vorhersage einfach die 'sequentielle' L individuelle Vorhersage und die 2. Frage ist gelöst.

Aber es ist verwirrend für mich noch, dass, wenn eine Meta-Klassifikator OneVsRestClassifier enthält L Klassifizierer, wie kann GridSearchCV gibt nur EINS beste Ergebnis, entsprechend einer von 4 * 2 * 4 Sätze von Parametern für eine meta-Klassifikator OneVsRestClassifier mit L Klassifikatoren?

Es würde ziemlich geschätzt werden, irgendeinen Kommentar zu sehen.

Antwort

4

GridSearchCV Raster von Ihren Parameterwerten erstellt, es wertet Ihre OneVsRestClassifier als Atom Sichter (Ie GridSearchCV weiß nicht, was in diesem metaclassifier ist)

Erste: 0,85 ist das beste Ergebnis von OneVsRestClassifier unter allen möglichen Kombinationen (16 Kombinationen in Ihrem Fall, 4 * 2 * 4) der Parameter ("estimator__C", "estimator__kernel", "estimator__degree"), es bedeutet GridSearchCV wertet 16 (wieder ist es nur in diesem speziellen Fall) möglich OneVsRestClassifier 's von denen jede enthält L SVC' s. All das L Klassifizierer innerhalb eines OneVsRestClassifier haben gleiche Werte von Parametern (aber jeder von ihnen lernen, ihre eigene Klasse von L möglich zu erkennen) ist es ein

dh von Satz

{OneVsRestClassifier(SVC(C=1, kernel="poly", degree=1)), 
OneVsRestClassifier(SVC(C=1, kernel="poly", degree=2)), 
..., 
OneVsRestClassifier(SVC(C=8, kernel="rbf", degree=3)), 
OneVsRestClassifier(SVC(C=8, kernel="rbf", degree=4))} 

mit der besten wählt Ergebnis.

model_tunning.best_params_ stellt hier Parameter für OneVsRestClassifier (SVC()), mit denen es model_tunning.best_score_ erreichen wird. Sie können das beste OneVsRestClassifier von model_tunning.best_estimator_ Attribut bekommen.

Zweitens: Es gibt keine betriebsbereit Code verwenden getrennte Noten von OneVsRestClassifier für L Klassifizierer zu erhalten, aber Sie können bei der Implementierung von OneVsRestClassifier.fit Methode suchen, oder nehmen Sie diese (sollte funktionieren :)):

# Here X, y - your dataset 
one_vs_rest = model_tunning.best_estimator_ 
yT = one_vs_rest.label_binarizer_.transform(y).toarray().T 
# Iterate through all L classifiers 
for classifier, is_ith_class in zip(one_vs_rest.estimators_, yT): 
    print(classifier.score(X, is_ith_class)) 
+0

Danke! In der ersten gibt es 4 * 2 * 4 'OneVsRestClassifier's in der Menge und jede davon entspricht' L' Klassifikatoren, die denselben Parametersatz verwenden. Ich frage mich also, warum es nur einen Score für einen Set-Parameter gibt und nicht für "L". Ist 0,85 das beste Ergebnis unter 4 * 2 * 4 * 'L' Modellen? – Francis

+0

@Francis, Nein, 0,85 ist das beste Ergebnis unter 4 * 2 * 4 OneVsRestClassifier (Weil Sie 4 * 2 * 4 Kombinationen von Parametern für diesen Klassifikator haben). GridSearchCV wertet einfach OneVsRestClassifier für jede mögliche Kombination aus und wählt eine mit der besten Genauigkeit aus. Sie können alle möglichen Kombinationen von Parametern und entsprechenden Scores aus dem Grid_scores_ Attribut von GridSearchCV erhalten, aber wenn Sie getrennte Scores für L Classifiers von jedem OneVsRestClassifier wollen (also 4 * 2 * 4 * L Scores) - sollten Sie Ihren eigenen Code schreiben. Sorry für mein Englisch vielleicht ist etwas nicht klar aus dem, was ich versuchte zu erklären. –

+0

Nein, es ist eigentlich mein Englisch ist nicht gut, da ich kein Muttersprachler bin :). Ich denke, dass ich das Verhalten von GridSearchCV auf dem Meta-Klassifikator herausgefunden habe, bitte helfen Sie mir, die Antwort zu klären, danke! – Francis

3

Angeregt durch @Olologins Antwort erkannte ich, dass 0,85 der beste gewichtete Durchschnitt der f1 Werte (in diesem Beispiel) ist, die durch L Vorhersagen erhalten wurden. Im folgenden Code, bewerte ich das Modell von Innen Test unter Verwendung der Makro durchschnittlich f1 score:

# Case A, inspect F1 score using the meta-classifier 
F_A = f1_score(y, model_tunning.best_estimator_.predict(X), average='macro') 

# Case B, inspect F1 scores of each label (binary task) and collect them by macro average 
F_B = [] 
for label, clc in zip(y.T, model_tunning.best_estimator_.estimators_): 
    F_B.append(f1_score(label, clf.predict(X))) 
F_B = mean(F_B) 

F_A==F_B # True 

So bedeutet es, dass die GridSearchCV eine von 4 * 2 * 4 Sätzen von Parametern gilt das Meta-Klassifikator zu bauen was wiederum die Vorhersage auf jedem Etikett mit einem der Klassifizierer L macht. Das Ergebnis wird L F1-Werte für L Etiketten sein, von denen jede eine Leistung einer binären Aufgabe ist. Schließlich wird eine einzelne Punktzahl erhalten, indem der Durchschnitt (Makro oder gewichteter Durchschnitt, spezifiziert durch den Parameter in f1_score) von L f1 Bewertungen genommen wird.

Die GridSearchCV dann wählen Sie die besten gemittelten F1-Bewertungen unter 4 * 2 * 4 Sätze von Parametern, die 0,85 in diesem Beispiel ist.

Obwohl es bequem ist, den Wrapper für Multi-Label-Problem zu verwenden, kann es nur den gemittelten f1-Score mit dem gleichen Parametersatz maximieren, der zum Erstellen von L Klassifikatoren verwendet wird. Wenn man die Leistung jedes Etiketts separat optimieren möchte, muss man anscheinend L Klassifikatoren erstellen, ohne den Wrapper zu verwenden.

+0

> Wenn Sie die Leistung jedes Etiketts einzeln optimieren möchten, müssen Sie L-Klassifizierer erstellen, ohne den Wrapper zu verwenden. Ja, Sie haben es richtig verstanden. –

+0

Vielen Dank! So scheint es mir, dass man den Wrapper verwenden sollte, wenn die Optimierung für jede Klasse nicht das Hauptanliegen ist. Denn abgesehen davon und der Bequemlichkeit gibt es keinen anderen Unterschied zwischen der Verwendung des Wrappers und dem Erstellen von "L" -Modellen von Hand. – Francis

1

Wie für Ihre zweite Frage, möchten Sie vielleicht GridSearchCV mit scikit-multilearn 's BinaryRelevance Klassifikator verwenden. Wie bei OneVsRestClassifier erzeugt Binary Relevance L-Label-Klassifikatoren, eins pro Label. Für jedes Etikett sind die Trainingsdaten 1, wenn ein Etikett vorhanden ist, und 0, falls nicht vorhanden. Der am besten ausgewählte Klassifizierungssatz ist die Klasseninstanz BinaryRelevance in best_estimator_, Eigenschaft GridSearchCV. Verwenden Sie zum Vorhersagen von Gleitkommazahlen von Wahrscheinlichkeiten die predict_proba-Methode des Objekts BinaryRelevance. Ein Beispiel findet sich in der.

In Ihrem Fall würde ich den folgenden Code ausführen:

from skmultilearn.problem_transform import BinaryRelevance 
from sklearn.model_selection import GridSearchCV 
import sklearn.metrics 

model_to_set = BinaryRelevance(SVC()) 

parameters = { 
    "classifier__estimator__C": [1,2,4,8], 
    "classifier__estimator__kernel": ["poly","rbf"], 
    "classifier__estimator__degree":[1, 2, 3, 4], 
} 

model_tunning = GridSearchCV(model_to_set, param_grid=parameters, 
          scoring='f1') 

model_tunning.fit(X, y) 

# for some X_test testing set 
predictions = model_tunning.best_estimator_.predict(X_test) 

# average=None gives per label score 
metrics.f1_score(y_test, predictions, average = None) 

Bitte beachten Sie, dass es viel bessere Methoden für Multi-Label-Klassifikation als Binary Relevanz :) Sie können sie in madjarov's comparison oder my recent paper finden.

Verwandte Themen