Unsymmetrische Multiklassendaten mit XGBoost

17

Ich habe 3 Klassen mit dieser Verteilung:

Class 0: 0.1169
Class 1: 0.7668
Class 2: 0.1163

Und ich benutze xgboostfür die Klassifizierung. Ich weiß, dass es einen Parameter namens gibt scale_pos_weight.

Aber wie wird es bei "Multiclass" -Fällen gehandhabt und wie kann ich es richtig einstellen?

shda
quelle

Antworten:

16

scale_pos_weightwird für die Binärklassifizierung verwendet, wie Sie angegeben haben. Es ist eine allgemeinere Lösung für den Umgang mit unausgeglichenen Klassen. Ein guter Ansatz, wenn Sie einen Wert zuweisen, scale_pos_weightist:

sum(negative instances) / sum(positive instances)

Für Ihren speziellen Fall gibt es eine andere Option, um einzelne Datenpunkte zu gewichten und ihre Gewichte zu berücksichtigen, während Sie mit dem Booster arbeiten, und die Optimierung in Bezug auf ihre Gewichte zuzulassen, sodass jeder Punkt gleich dargestellt wird. Sie müssen nur einfach verwenden:

xgboost.DMatrix(..., weight = *weight array for individual weights*)

Sie können die Gewichte so definieren, wie Sie möchten, und auf diese Weise können Sie sogar Ungleichgewichte innerhalb von Klassen sowie Ungleichgewichte über verschiedene Klassen hinweg behandeln.

Kerem T
quelle
> Ein guter Ansatz, wenn Sie scale_pos_weight einen Wert zuweisen, ist: sum (negative Instanzen) / sum (positive Instanzen)
lcrmorin
1
Ich sehe diesen Rat überall und es ist sinnvoll, der weniger vertretenen Klasse ein höheres Gewicht zuzuweisen. Es fällt mir jedoch schwer, eine Quelle zu finden, die diesen genauen Wert bespricht. Ich verstehe die Intuition hinter diesem spezifischen Wert (mache die Stichprobe ausgewogen), aber ich vermute, dass es irgendwo einen Varianz-Kompromiss gibt, der Sie dazu bringen würde, ein geringeres Gewicht in Betracht zu ziehen.
Lcrmorin
6

Diese Antwort von @KeremT ist richtig. Ich gebe ein Beispiel für diejenigen, die noch Probleme mit der genauen Implementierung haben.

weightParameter in XGBoost ist pro Instanz nicht pro Klasse. Daher müssen wir das Gewicht jeder Klasse ihren Instanzen zuweisen, was dasselbe ist.

Zum Beispiel, wenn wir drei unausgeglichene Klassen mit Verhältnissen haben

class A = 10%
class B = 30%
class C = 60%

Ihre Gewichte wären (Teilen der kleinsten Klasse durch andere)

class A = 1.000
class B = 0.333
class C = 0.167

Dann, wenn Trainingsdaten sind

index   class
0       A
1       A
2       B
3       C
4       B

Wir bauen den weightVektor wie folgt auf:

index   class    weight
0       A        1.000
1       A        1.000
2       B        0.333
3       C        0.167
4       B        0.333
Esmailian
quelle
3

Jeder stolpert über diese Frage, wenn er sich mit einem Problem der unausgewogenen Klassifizierung mehrerer Klassen mit XGBoost in R befasst. Das habe ich auch getan!

Ich suchte nach einem Beispiel, um besser zu verstehen, wie man es anwendet. Investiert fast eine Stunde, um den unten genannten Link zu finden. Für alle, die ein Beispiel suchen, hier geht's -

/datascience//a/9493/37156

Danke wacax

Krithi07
quelle
0

Ordnen Sie einfach jeder Instanz Ihrer Zugdaten das Klassengewicht zu. class_weight.compute_class_weightHolen Sie sich zuerst die Klassengewichte mit von sklearn und weisen Sie dann jeder Zeile der Zugdaten das entsprechende Gewicht zu.

Ich gehe hier davon aus, dass die Zugdaten die Spalte 'Klasse' haben, die die Klassennummer enthält. Ich habe auch angenommen, dass es nb_classes von 1 bis nb_classes gibt.

from sklearn.utils import class_weight
class_weights = list(class_weight.compute_class_weight('balanced',
                                             np.unique(train['class']),
                                             train['class']))

w_array = np.ones(y_train.shape[0], dtype = 'float')
for i, val in enumerate(y_train):
    w_array[i] = class_weights[val-1]

xgb_classifier.fit(X, y, sample_weight=w_array)
Firas Omrane
quelle