2016-04-08 9 views
0

Wie wird das gemacht? Ich benutze Sklearn, um eine SVM zu trainieren. Meine Klassen sind unausgewogen. Beachten Sie, dass mein Problem mehrklassige ist, so bin mit Multilabel OneVsRestClassifier I:Zuweisen einer Gewichtung zu einer Multilabel-SVM zum Ausgleichen von Klassen

mlb = MultiLabelBinarizer() 
y = mlb.fit_transform(y_train) 

clf = OneVsRestClassifier(svm.SVC(kernel='rbf')) 
clf = clf.fit(x, y) 
pred = clf.predict(x_test) 

Kann ich ein ‚sample_weight‘ Parameter irgendwo hinzufügen für die unausgeglichenen Klassen zu berücksichtigen?


Wenn ich einen class_weight dict zum SVM hinzufügen erhalte ich die Fehlermeldung:

ValueError: Class label 2 not present 

Das ist, weil ich meine Etiketten umgewandelt haben mit dem mlb binär. Allerdings, wenn ich nicht die Etiketten umwandeln, die ich erhalten:

ValueError: You appear to be using a legacy multi-label data representation. Sequence of sequences are no longer supported; use a binary array or sparse matrix instead. 

class_weight ist ein dict, das Mapping der Klasse Etiketten auf das Gewicht: {1: 1, 2: 1, 3: 3 ...}

Hier sind die Details von x und y:

print(X[0]) 
[ 0.76625633 0.63062721 0.01954162 ..., 1.1767817 0.249034 0.23544988] 
print(type(X)) 
<type 'numpy.ndarray'> 

print(y[0]) 
print(type(y)) 
[1, 2, 3, 4, 5, 6, 7] 
<type 'numpy.ndarray'> 

Beachten Sie, dass mlb = MultiLabelBinarizer(); y = mlb.fit_transform (y_train) konvertiert y in ein binäres Array.


Die vorgeschlagene Antwort erzeugt den Fehler:

ValueError: You appear to be using a legacy multi-label data representation. Sequence of sequences are no longer supported; use a binary array or sparse matrix instead. 

Also, das Problem reduziert die Etiketten zu konvertieren (a np.array) zu einer Sparse Matrix.

from scipy import sparse 
y_sp = sparse.csr_matrix(y) 

Dies erzeugt den Fehler:

TypeError: no supported conversion for types: (dtype('O'),) 

Ich werde eine neue Abfrage für diese öffnen.

+0

Könnten Sie ein zur Verfügung stellen Element von x Andy ? 'Druckart (x [0]) Druck x [0]' und 'Druckart (y [0]) Druck y [0]' – dooms

+0

Hier ist das y nicht binär. Sehen Sie, ob 'mlb.classes_' Ihnen ein Array mit dem Wert 2 gibt. – dooms

+0

Ich habe versucht, die Etiketten in binäre umzuwandeln. Es erzeugt den oben aufgeführten Fehler: ValueError: Klassenlabel 2 nicht vorhanden (weil alle Beschriftungen dann im Binärformat sind). Wenn ich nicht in binäre konvertieren, erhalte ich den Fehler: ValueError: Sie scheinen eine ältere Multi-Label-Datendarstellung zu verwenden. Sequenzen von Sequenzen werden nicht mehr unterstützt. Verwenden Sie stattdessen ein Binärarray oder eine Sparse-Matrix. –

Antwort

1

könnten Sie verwenden:

class_weight : {dict, ‘balanced’}, optional

Set the parameter C of class i to class_weight[i]*C for SVC. If not given, all classes are supposed to have weight one. The “balanced” mode uses the values of y to automatically adjust weights inversely proportional to class frequencies in the input data as n_samples/(n_classes * np.bincount(y))

clf = OneVsRestClassifier(svm.SVC(kernel='rbf', class_weight='balanced')) 

+0

Danke, können Sie ein Codebeispiel geben? Wenn ich das versuche, erhalte ich den Fehler: ValueError: Klassenlabel 2 nicht vorhanden, weil ich meine Etiketten in binäre umgewandelt habe. ABER, wenn ich die Beschriftungen nicht konvertiere, bekomme ich: valueError: Sie scheinen eine ältere Multi-Label-Datendarstellung zu verwenden.Sequenzen von Sequenzen werden nicht mehr unterstützt. Verwenden Sie stattdessen ein Binärarray oder eine Sparse-Matrix. –

+0

Könnten Sie mir die Fehlermeldung geben? Hier ist ein [zufälliges Beispiel] (https://github.com/mstampfer/Equities/blob/2c8e23d4f77c51261fe97ce53cf13d043d9ef8e5/GridSearchParams.py#L16) – Till

+0

Ist dieser Fehler mit dem Attribut 'class_weight' verbunden? Hattest du diesen Fehler vorher? – Till

0

Dieser Code funktioniert gut mit dem 'ausgewogen' Wert von class_weight Attribut

>>> from sklearn.preprocessing import MultiLabelBinarizer 
>>> from sklearn.svm import SVC 
>>> from sklearn.multiclass import OneVsRestClassifier 

>>> mlb = MultiLabelBinarizer() 
>>> x = [[0,1,1,1],[1,0,0,1]] 
>>> y = mlb.fit_transform([['sci-fi', 'thriller'], ['comedy']]) 

>>> print y 
>>> print mlb.classes_ 
[[0 1 1] 
[1 0 0]] 
['comedy' 'sci-fi' 'thriller'] 

>>> OneVsRestClassifier(SVC(random_state=0, class_weight='balanced')).fit(x, y).predict(x) 
array([[0, 1, 1], 
    [1, 0, 0]]) 
+0

Ich habe ausgewogen verwendet, möchte aber benutzerdefinierte Gewichtungen angeben. –