Datos multiclase desequilibrados con XGBoost


20

Tengo 3 clases con esta distribución:

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

Y estoy usando xgboostpara la clasificación. Sé que hay un parámetro llamado scale_pos_weight.

Pero, ¿cómo se maneja para el caso 'multiclase' y cómo puedo configurarlo correctamente?

Respuestas:


18

scale_pos_weightse usa para la clasificación binaria como usted indicó. Es una solución más generalizada para manejar clases desequilibradas. Un buen enfoque al asignar un valor a scale_pos_weightes:

sum(negative instances) / sum(positive instances)

Para su caso específico, existe otra opción para ponderar los puntos de datos individuales y tener en cuenta sus pesos mientras trabaja con el refuerzo, y permitir que la optimización ocurra con respecto a sus pesos para que cada punto se represente por igual. Solo necesita simplemente usar:

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

Puede definir los pesos como desee y, al hacerlo, incluso puede manejar los desequilibrios dentro de las clases, así como los desequilibrios en las diferentes clases.


> Un buen enfoque al asignar un valor a scale_pos_weight es: suma (instancias negativas) / suma (instancias positivas)
lcrmorin

1
Veo este consejo en todas partes y tiene sentido asignar un mayor peso a la clase menos representada. Sin embargo, me cuesta encontrar una fuente que discuta este valor exacto. Tengo la intuición detrás de ese valor específico (hacer que la muestra sea equilibrada) pero sospecho que hay una compensación de varianza en alguna parte, que haría que desee considerar un peso más bajo.
lcrmorin

7

Esta respuesta de @KeremT es correcta. Proporciono un ejemplo para aquellos que todavía tienen problemas con la implementación exacta.

weightEl parámetro en XGBoost es por instancia, no por clase. Por lo tanto, debemos asignar el peso de cada clase a sus instancias, que es lo mismo.

Por ejemplo, si tenemos tres clases desequilibradas con relaciones

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

Sus pesos serían (dividiendo la clase más pequeña por otras)

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

Entonces, si los datos de entrenamiento son

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

construimos el weightvector de la siguiente manera:

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

5

Todos se topan con esta pregunta cuando se trata de un problema de clasificación multiclase desequilibrado usando XGBoost en R. ¡Yo también!

Estaba buscando un ejemplo para comprender mejor cómo aplicarlo. Invertí casi una hora para encontrar el enlace mencionado a continuación. Para todos aquellos que buscan un ejemplo, aquí va:

/datascience//a/9493/37156

Gracias wacax


0

Simplemente asigne cada instancia de sus datos de tren con su peso de clase. Primero obtenga los pesos de clase class_weight.compute_class_weightde sklearn y luego asigne a cada fila de datos del tren su peso apropiado.

Asumo aquí que los datos del tren tienen la columna 'clase' que contiene el número de clase. Supuse también que hay nb_classes que son de 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)
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.