Ich habe große Probleme zu verstehen, wie der class_weight
Parameter in der logistischen Regression von scikit-learn funktioniert.
Die Situation
Ich möchte die logistische Regression verwenden, um eine binäre Klassifizierung für einen sehr unausgeglichenen Datensatz durchzuführen. Die Klassen sind mit 0 (negativ) und 1 (positiv) gekennzeichnet, und die beobachteten Daten liegen in einem Verhältnis von etwa 19: 1 vor, wobei die Mehrzahl der Proben ein negatives Ergebnis aufweist.
Erster Versuch: Manuelles Vorbereiten von Trainingsdaten
Ich teilte die Daten, die ich hatte, in disjunkte Sätze zum Trainieren und Testen auf (ungefähr 80/20). Dann habe ich die Trainingsdaten zufällig von Hand abgetastet, um Trainingsdaten in anderen Proportionen als 19: 1 zu erhalten. von 2: 1 -> 16: 1.
Ich habe dann die logistische Regression für diese verschiedenen Trainingsdaten-Teilmengen trainiert und den Rückruf (= TP / (TP + FN)) als Funktion der verschiedenen Trainingsproportionen aufgezeichnet. Natürlich wurde der Rückruf an den disjunkten TEST-Proben berechnet, die die beobachteten Verhältnisse von 19: 1 hatten. Hinweis: Obwohl ich die verschiedenen Modelle mit unterschiedlichen Trainingsdaten trainiert habe, habe ich den Rückruf für alle Modelle mit denselben (disjunkten) Testdaten berechnet.
Die Ergebnisse waren wie erwartet: Der Rückruf lag bei 2: 1-Trainingsverhältnissen bei etwa 60% und fiel ziemlich schnell ab, als er 16: 1 erreichte. Es gab verschiedene Anteile von 2: 1 -> 6: 1, bei denen der Rückruf anständig über 5% lag.
Zweiter Versuch: Rastersuche
Als nächstes wollte ich verschiedene Regularisierungsparameter testen und habe daher GridSearchCV verwendet und ein Raster aus mehreren Werten des C
Parameters sowie des class_weight
Parameters erstellt. Um meine n: m-Anteile an negativen: positiven Trainingsbeispielen in die Wörterbuchsprache von zu übersetzen, class_weight
dachte ich, dass ich nur mehrere Wörterbücher wie folgt spezifiziere:
{ 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 habe auch None
und aufgenommen auto
.
Diesmal waren die Ergebnisse total verrückt. Alle meine Rückrufe waren winzig (<0,05) für jeden Wert von class_weight
außer auto
. Daher kann ich nur davon ausgehen, dass mein Verständnis für das Einstellen des class_weight
Wörterbuchs falsch ist. Interessanterweise lag der class_weight
Wert von 'auto' in der Rastersuche für alle Werte von bei 59% C
, und ich vermutete, dass er sich auf 1: 1?
Meine Fragen
Wie verwenden Sie es richtig
class_weight
, um ein anderes Gleichgewicht in den Trainingsdaten zu erreichen, als Sie es tatsächlich geben? Welches Wörterbuch übergebe ich speziell,class_weight
um n: m-Anteile von negativen: positiven Trainingsmustern zu verwenden?Wenn Sie verschiedene
class_weight
Wörterbücher an GridSearchCV übergeben, werden während der Kreuzvalidierung die Daten der Trainingsfalte gemäß dem Wörterbuch neu gewichtet, aber die tatsächlich angegebenen Stichprobenanteile für die Berechnung meiner Bewertungsfunktion für die Testfalte verwendet? Dies ist wichtig, da jede Metrik für mich nur dann nützlich ist, wenn sie aus Daten in den beobachteten Anteilen stammt.Was macht der
auto
Wert vonclass_weight
in Bezug auf Proportionen? Ich habe die Dokumentation gelesen und gehe davon aus, dass "die Daten umgekehrt proportional zu ihrer Häufigkeit ausgleichen" nur bedeutet, dass sie 1: 1 sind. Ist das richtig? Wenn nicht, kann jemand klarstellen?
quelle
Antworten:
Zunächst einmal ist es möglicherweise nicht gut, nur durch Rückruf allein zu gehen. Sie können einfach einen Rückruf von 100% erreichen, indem Sie alles als positive Klasse klassifizieren. Normalerweise schlage ich vor, AUC zur Auswahl von Parametern zu verwenden und dann einen Schwellenwert für den Betriebspunkt (z. B. eine bestimmte Genauigkeitsstufe) zu finden, an dem Sie interessiert sind.
Wie es
class_weight
funktioniert: Es bestraft Fehler in Stichproben vonclass[i]
mitclass_weight[i]
statt 1. Ein höheres Klassengewicht bedeutet also, dass Sie mehr Gewicht auf eine Klasse legen möchten.class_weight
Nach Ihren Angaben ist Klasse 0 19-mal häufiger als Klasse 1. Sie sollten also die Klasse 1 relativ zur Klasse 0 erhöhen , z. B. {0: .1, 1: .9}. Wenn dieclass_weight
Summe nicht 1 ergibt, ändert sich der Regularisierungsparameter grundsätzlich.Wie das
class_weight="auto"
funktioniert, können Sie sich in dieser Diskussion ansehen . In der Dev-Version können Sie verwendenclass_weight="balanced"
, was einfacher zu verstehen ist: Es bedeutet im Grunde, die kleinere Klasse zu replizieren, bis Sie so viele Samples wie in der größeren haben, aber auf implizite Weise.quelle
Die erste Antwort ist gut, um zu verstehen, wie es funktioniert. Aber ich wollte verstehen, wie ich es in der Praxis anwenden sollte.
ZUSAMMENFASSUNG
class_weight="balanced"
funktioniert anständig, wenn Sie nicht manuell optimieren möchtenclass_weight="balanced"
Sie mehr wahre Ereignisse erfassen (höherer TRUE-Rückruf), erhalten Sie jedoch mit größerer Wahrscheinlichkeit falsche Warnungen (geringere TRUE-Genauigkeit).NB
Das Ergebnis kann bei Verwendung von RF oder GBM abweichen. sklearn hat nicht
class_weight="balanced"
für GBM, aber lightgbm hatLGBMClassifier(is_unbalance=False)
CODE
quelle