Risposte:
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.
Questa risposta di @KeremT è corretta. Fornisco un esempio per coloro che hanno ancora problemi con l'implementazione esatta.
weight
il 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 weight
vettore 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
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 -
Grazie Wacax
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)