Dati multiclasse non bilanciati con XGBoost


20

Ho 3 lezioni con questa distribuzione:

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

E sto usando xgboostper la classificazione. So che esiste un parametro chiamato scale_pos_weight.

Ma come viene gestito per il caso "multiclasse" e come posso impostarlo correttamente?

Risposte:


18

scale_pos_weightè usato per la classificazione binaria come hai affermato. È una soluzione più generalizzata per gestire le classi squilibrate. Un buon approccio quando si assegna un valore a scale_pos_weightè:

sum(negative instances) / sum(positive instances)

Per il tuo caso specifico, esiste un'altra opzione per ponderare i singoli punti dati e tener conto dei loro pesi mentre si lavora con il booster e consentire l'ottimizzazione rispetto ai loro pesi in modo che ogni punto sia rappresentato equamente. Hai solo bisogno di usare semplicemente:

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

È possibile definire i pesi come desiderato e, in tal modo, è anche possibile gestire gli squilibri all'interno delle classi e gli squilibri tra le diverse classi.


> Un buon approccio quando si assegna un valore a scale_pos_weight è: sum (istanze negative) / sum (istanze positive)
lcrmorin

1
Vedo questo consiglio ovunque ed ha senso assegnare un peso maggiore alla classe meno rappresentata. Tuttavia ho difficoltà a trovare una fonte che discute questo valore esatto. Ottengo l'intuizione dietro quel valore specifico (rendere il campione bilanciato) ma sospetto che ci sia un compromesso di varianza da qualche parte, che ti farebbe desiderare di considerare un peso inferiore.
lcrmorin,

7

Questa risposta di @KeremT è corretta. Fornisco un esempio per coloro che hanno ancora problemi con l'implementazione esatta.

weightil parametro in XGBoost non è per istanza per classe. Pertanto, dobbiamo assegnare il peso di ogni classe alle sue istanze, che è la stessa cosa.

Ad esempio, se abbiamo tre classi squilibrate con rapporti

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

I loro pesi sarebbero (dividendo la classe più piccola per gli altri)

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

Quindi, se i dati di allenamento sono

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

costruiamo il weightvettore come segue:

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

5

Tutti si imbattono in questa domanda quando si tratta di un problema di classificazione multiclasse sbilanciato usando XGBoost in R. Anche io!

Stavo cercando un esempio per capire meglio come applicarlo. Ho investito quasi un'ora per trovare il link menzionato di seguito. Per tutti coloro che cercano un esempio, ecco qui -

/datascience//a/9493/37156

Grazie Wacax


0

Assegna a ciascuna istanza dei dati del tuo treno il peso della sua classe. Per prima cosa prendi i pesi della classe conclass_weight.compute_class_weight sklearn, quindi assegna a ciascuna riga dei dati del treno il peso appropriato.

Presumo qui che i dati del treno abbiano la colonna 'class' contenente il numero di classe. Ho anche ipotizzato che ci siano nb_classes che vanno da 1 a 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)
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.