Niezrównoważone dane wieloklasowe dzięki XGBoost

20

Mam 3 klasy z tą dystrybucją:

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

I używam xgboostdo klasyfikacji. Wiem, że istnieje parametr o nazwie scale_pos_weight.

Ale jak to jest obsługiwane w przypadku „wieloklasowym” i jak mogę to właściwie ustawić?

shda
źródło

Odpowiedzi:

18

scale_pos_weightjest używany do klasyfikacji binarnej, jak powiedziałeś. Jest to bardziej ogólne rozwiązanie do obsługi niezrównoważonych klas. Dobrym podejściem przy przypisywaniu wartości scale_pos_weightjest:

sum(negative instances) / sum(positive instances)

W konkretnym przypadku istnieje inna opcja ważenia poszczególnych punktów danych i uwzględnienia ich wag podczas pracy ze wzmacniaczem oraz umożliwienia optymalizacji ich wag, tak aby każdy punkt był reprezentowany równo. Musisz po prostu użyć:

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

Możesz zdefiniować wagi według własnych upodobań, a tym samym poradzić sobie z zaburzeniami równowagi w ramach klas, a także zaburzeniami równowagi w różnych klasach.

Kerem T.
źródło
> Dobrym podejściem przy przypisywaniu wartości do scale_pos_weight jest: suma (instancje ujemne) / sum (instancje dodatnie)
lcrmorin
1
Widzę tę radę wszędzie i sensowne jest przypisywanie większej wagi mniej reprezentowanej klasie. Jednak trudno mi znaleźć źródło omawiające tę dokładną wartość. Czuję intuicję za tą konkretną wartością (zbalansuj próbkę), ale podejrzewam, że istnieje gdzieś kompromis wariancji, który sprawiłby, że chcesz rozważyć mniejszą wagę.
lcrmorin
7

Ta odpowiedź @KeremT jest poprawna. Podaję przykład dla tych, którzy nadal mają problemy z dokładną implementacją.

weightparametr w XGBoost jest na instancję, a nie na klasę. Dlatego musimy przypisać wagę każdej klasy do jej instancji, co jest tym samym.

Na przykład, jeśli mamy trzy niezbilansowane klasy ze współczynnikami

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

Ich wagi byłyby (dzieląc najmniejszą klasę przez innych)

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

Następnie, jeśli dane treningowe są

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

weightwektor budujemy w następujący sposób:

index   class    weight
0       A        1.000
1       A        1.000
2       B        0.333
3       C        0.167
4       B        0.333
E-mail
źródło
5

Wszyscy natkną się na to pytanie, mając do czynienia z problemem niezrównoważonej klasyfikacji wieloklasowej za pomocą XGBoost w R. Ja też to zrobiłem!

Szukałem przykładu, aby lepiej zrozumieć, jak go zastosować. Zainwestował prawie godzinę, aby znaleźć link wymieniony poniżej. Dla wszystkich, którzy szukają przykładu, oto -

/datascience//a/9493/37156

Dzięki Wacax

Krithi07
źródło
1

Po prostu przypisz każdemu wystąpieniu danych pociągu wagę klasy. Najpierw uzyskaj wagi klasy ze class_weight.compute_class_weightsklearn, a następnie przypisz każdemu rzędowi danych pociągu odpowiednią wagę.

Zakładam tutaj, że dane pociągu mają kolumnę „klasa” zawierającą numer klasy. Zakładałem również, że istnieją klasy nb od 1 do nb_classes.

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
źródło