2015-06-22 4 views
49

Ich habe viel Mühe zu verstehen, wie der class_weight Parameter in scikit-learns Logistische Regression funktioniert.Wie funktioniert der Parameter class_weight in scikit-learn?

Die Situation

I logistische Regression zu tun binäre Klassifizierung auf einem sehr unausgeglichen Datensatz verwendet werden soll. Die Klassen sind mit 0 (negativ) und 1 (positiv) gekennzeichnet, und die beobachteten Daten stehen in einem Verhältnis von etwa 19: 1, wobei die Mehrheit der Proben ein negatives Ergebnis aufweist.

erster Versuch: Manuelles Vorbereiten Trainingsdaten

ich teilte die Daten, die ich für die Ausbildung und Prüfung (ca. 80/20) in disjunkte Mengen hatte. Dann habe ich zufällig die Trainingsdaten per Hand abgetastet, um Trainingsdaten in unterschiedlichen Proportionen als 19: 1 zu erhalten; von 2: 1 -> 16: 1.

Dann trainierte ich logistische Regression auf diesen verschiedenen Trainingsdaten Teilmengen und zeichnete Recall (= TP/(TP + FN)) als eine Funktion der verschiedenen Trainingsanteile. Natürlich wurde der Rückruf an den disjunkten TEST-Proben berechnet, die die beobachteten Anteile von 19: 1 aufwiesen. Hinweis: Obwohl ich die verschiedenen Modelle für verschiedene Trainingsdaten trainierte, berechnete ich sie für alle auf denselben (disjunkten) Testdaten.

Die Ergebnisse waren wie erwartet: Der Rückruf betrug etwa 60% bei 2: 1 Trainingsproportionen und fiel bis zum 16: 1 ziemlich schnell ab. Es gab mehrere Proportionen 2: 1 -> 6: 1, bei denen der Rückruf anständig über 5% lag.

Zweiter Versuch: Grid Search

Als nächstes wollte ich verschiedene Regularisierungsparameter testen und so habe ich GridSearchCV und machte ein Raster von mehreren Werten des C Parameter sowie die class_weight Parameter. Zu übersetzen, meine n: m Proportionen negativ: positive Trainingsmuster in das Wörterbuch Sprache class_weight Ich dachte, dass ich nur mehrere Wörterbücher wie folgt an:

{ 0:0.67, 1:0.33 } #expected 2:1 
{ 0:0.75, 1:0.25 } #expected 3:1 
{ 0:0.8, 1:0.2 } #expected 4:1 

und ich gehörte auch None und auto.

Dieses Mal waren die Ergebnisse völlig verrückt. Alle meine Rückrufe kamen für jeden Wert von mit Ausnahme von auto winzig heraus (<). Also kann ich nur annehmen, dass mein Verständnis, wie man das class_weight Wörterbuch setzt, falsch ist. Interessanterweise war der class_weight Wert von 'auto' in der Grid-Suche für alle Werte von C um 59%, und ich vermutete, dass er auf 1: 1 ausbalanciert ist?

Meine Fragen

1) Wie richtig Sie class_weight verwenden, um verschiedene Salden in Trainingsdaten aus zu erreichen, was Sie tatsächlich geben? Insbesondere, welches Wörterbuch übergebe ich an class_weight, um n: m Anteile von negativ zu verwenden: positive Trainingsstichproben?

2) Wenn Sie verschiedene Wörterbücher von class_weight an GridSearchCV übergeben, werden bei der Kreuzvalidierung die Trainingsfaltungsdaten gemäß dem Wörterbuch neu gewichtet, aber die richtigen Proportionen für die Berechnung meiner Bewertungsfunktion auf der Testfalte verwendet?Dies ist kritisch, da jede Metrik nur dann nützlich ist, wenn sie aus Daten in den beobachteten Proportionen stammt.

3) Was bedeutet der auto Wert von class_weight als Proportionen so weit tun? Ich lese die Dokumentation und ich nehme an, dass "die Daten umgekehrt proportional zu ihrer Frequenz ausbalanciert" bedeutet nur, dass es 1: 1 macht. Ist das richtig? Wenn nicht, kann jemand klären?

Vielen Dank, jede Klarstellung würde sehr geschätzt werden!

Antwort

49

Zunächst einmal ist es vielleicht nicht gut, nur nach Rückruf allein zu gehen. Sie können einfach einen Rückruf von 100% erreichen, indem Sie alles als positive Klasse klassifizieren. Ich schlage vor, in der Regel AUC unter Verwendung von Parametern auswählen und dann einen Schwellenwert für den Betriebspunkt zu finden (zB eine bestimmte Genauigkeitsstufe), die Sie interessiert sind

Für wie class_weight Werke:. Es bestraft Fehler in Proben von class[i] mit class_weight[i] statt 1. Also bedeutet höheres Klassengewicht, dass Sie mehr Gewicht auf eine Klasse legen wollen. Von dem, was Sie sagen, scheint Klasse 19 19 Mal häufiger als Klasse 1 zu sein. Sie sollten also die class_weight der Klasse 1 relativ zur Klasse 0 erhöhen, sagen wir {0: .1, 1: .9}. Wenn die class_weight nicht zu 1 summiert, wird der Regularisierungsparameter grundlegend geändert.

Für wie funktioniert class_weight="auto" funktioniert, können Sie sehen this discussion. In der Entwicklungsversion können Sie class_weight="balanced" verwenden, was einfacher zu verstehen ist: es bedeutet im Grunde, die kleinere Klasse zu replizieren, bis Sie so viele Samples wie in dem größeren haben, aber auf implizite Weise.

+0

Danke! Schnelle Frage: Ich erwähnte, dass ich mich aus Gründen der Klarheit erinnern möchte und in der Tat versuche ich zu entscheiden, welche AUC als meine Maßnahme verwendet werden soll. Mein Verständnis ist, dass ich entweder Bereich unter ROC-Kurve oder Bereich unter Recall vs. Präzision Kurve maximieren sollte, um Parameter zu finden. Nachdem ich die Parameter auf diese Weise ausgewählt habe, glaube ich, dass ich die Schwelle für die Klassifizierung durch Gleiten entlang der Kurve wähle. Hast du das gemeint? Wenn ja, welche der beiden Kurven ist am sinnvollsten, wenn es mein Ziel ist, so viele TPs wie möglich zu erfassen? Danke auch für Ihre Arbeit und Beiträge zum scikit-learn !!! – ministry

+1

Ich denke, die Verwendung von ROC wäre der Standardweg, aber ich denke nicht, dass es einen großen Unterschied geben wird. Sie benötigen jedoch ein Kriterium, um den Punkt auf der Kurve auszuwählen. –

+0

Gibt es nicht auch die Idee, eine Fehlklassifikation Ihres kleineren Sets in diesem Szenario stärker zu bestrafen? Obwohl ich zustimme, dass die Sache zu versuchen ist, ist die ausgewogene Einstellung für den Parameter class_weight. –

Verwandte Themen