2014-02-19 10 views
7

Ich habe versucht, gewichtete Samples in scikit-learn zu verwenden, während ich einen Random Forest Classifier trainiere. Es funktioniert gut, wenn ich eine Probengewichtung direkt an den Klassifizierer weiterleite, z. RandomForestClassifier().fit(X,y,sample_weight=weights), aber wenn ich eine Rastersuche versucht, besser Hyper für den Klassifikator zu finden, schlug ich eine Wand:Beispielgewichte in scikit-learn gebrochene Kreuzvalidierung

die Gewichte zu übergeben, wenn der Raster Parameter verwendet, ist die Nutzung:

grid_search = GridSearchCV(RandomForestClassifier(), params, n_jobs=-1, 
          fit_params={"sample_weight"=weights}) 

Das Problem ist, dass der Kreuzvalidator keine Stichprobengewichte kennt und diese daher nicht zusammen mit den tatsächlichen Daten neu abtastet, so dass der Aufruf grid_search.fit(X,y) fehlschlägt: Der Kreuzvalidator erzeugt Teilmengen von X und y, sub_X und sub_y und schließlich einen Klassifizierer aufgerufen mit classifier.fit(sub_X, sub_y, sample_weight=weights) aber jetzt Gewichte wurde nicht neu abgetastet, so dass eine Ausnahme ausgelöst wird.

Für jetzt habe ich um das Problem herum gearbeitet, indem ich Proben mit hohem Gewicht überbeprobt habe, bevor ich den Klassifikator trainiere, aber es ist ein vorübergehender Workaround. Irgendwelche Vorschläge zum weiteren Vorgehen?

Antwort

2

Ich würde vorschlagen, eigene Kreuzvalidierung Parameter Auswahl zu schreiben, wie es nur 10-15 Zeilen Code (vor allem mit dem kfold Objekt von Scikit-lernen) in Python, während Oversampling ist möglicherweise ein großer Engpass.

+1

Das Problem ist, dass GridSearchCV die Kreuzvalidierung in seinen Code eingebettet hat. Ich habe kein Problem, das zu ändern, aber es scheint mir dreckig zu sein. Sind die beiden Ansätze (Resampling und Gewichtung) als Meta-Frage tatsächlich gleichwertig? hmm, schaute ein bisschen hinein und es scheint, dass sie nicht sind aber auch, dass beide gut funktionieren: http://statistics.berkeley.edu/sites/default/files/tech-reports/666.pdf –

+1

Ich fing an, Hyperparameter-Suche zu modifizieren ('fit_grid_point' in grid_search.py), um Klassengewichte zu berücksichtigen, und dann erkannte ich, dass es in scikit-learn noch ein weiteres eklatantes Unterlassen gibt: Das Scoring in der Kreuzvalidierung wird auch die Klassengewichte nicht berücksichtigen (mir ist mehr wichtig die Minderheitsklasse bei der Bewertung des Fehlers falsch klassifizieren). Das alles bringt mich dazu, Resampling durchzuführen und dieses Problem nur dann richtig zu beheben, wenn ich auf Performance-Probleme stoße. –

5

Edit: die Punkte, die ich von unten sehe, scheinen nicht ganz richtig. Dies liegt möglicherweise daran, dass, wie oben erwähnt, selbst wenn Gewichte bei der Anpassung verwendet werden, sie möglicherweise nicht beim Scoring verwendet werden.

Es scheint, dass dies jetzt behoben wurde. Ich betreibe Sklearn Version 0.15.2. Mein Code sieht ungefähr so ​​aus:

model = SGDRegressor() 
parameters = {'alpha':[0.01, 0.001, 0.0001]} 
cv = GridSearchCV(model, parameters, fit_params={'sample_weight': weights}) 
cv.fit(X, y) 

Hoffe, dass hilft (Sie und andere, die diesen Beitrag sehen).

2

Ich habe zu wenig Ruf, so kann ich @xenocyon nicht kommentieren. Ich benutze sklearn 0.18.1 und benutze auch eine Pipeline im Code. Die Lösung, die für mich funktionierte, war:

fit_params={'classifier__sample_weight': w} wo w ist der Gewichtsvektor und classifier ist der Schrittname in der Pipeline.

+0

das hat es für mich getan! Was für ein toller Fang. – bwest87