76 votos

¿Cuál es el uso adecuado de scale_pos_weight en xgboost para conjuntos de datos desequilibrados?

Tengo un conjunto de datos muy desequilibrado. Estoy tratando de seguir el consejos de afinación y utilizar scale_pos_weight pero no estoy seguro de cómo debo afinarla.

Puedo ver que RegLossObj.GetGradient lo hace:

if (info.labels[i] == 1.0f) w *= param_.scale_pos_weight

por lo que un gradiente de una muestra positiva sería más influyente. Sin embargo, según el papel xgboost se utiliza siempre la estadística del gradiente localmente \= dentro de las instancias de un nodo específico en un árbol específico:

  1. en el contexto de un nodo, para evaluar la reducción de pérdidas de una división candidata
  2. en el contexto de un nodo hoja, para optimizar el peso dado a ese nodo

Así que no hay manera de saber de antemano lo que sería un buen scale_pos_weight - es un número muy diferente para un nodo que termina con una proporción de 1:100 entre instancias positivas y negativas, y para un nodo con una proporción de 1:2.

¿Alguna pista?

73voto

sha Puntos 579

En general, scale_pos_weight es la relación entre el número de clases negativas y las positivas.

Supongamos que el conjunto de datos tiene 90 observaciones de clase negativa y 10 observaciones de clase positiva, entonces el valor ideal de scale_pos_weight debería ser 9.

Ver el documento: http://xgboost.readthedocs.io/en/latest/parameter.html

20voto

desikan Puntos 23

Toda la documentación dice que así debe ser:

scale_pos_weight = count(negative examples)/count(Positive examples)

En la práctica, esto funciona bastante bien, pero si su conjunto de datos está extremadamente desequilibrado, le recomendaría utilizar algo más conservador como:

scale_pos_weight = sqrt(count(negative examples)/count(Positive examples)) 

Esto es útil para limitar el efecto de una multiplicación de ejemplos positivos por un peso muy alto.

2voto

JohnThePro Puntos 1984

Entiendo tu pregunta y tu frustración, pero no estoy seguro de que esto sea algo que se pueda calcular analíticamente, más bien tendrías que determinar un buen ajuste empíricamente para tus datos, como lo haces para la mayoría de los hiperparámetros, utilizando la validación cruzada como sugirió @user2149631. He tenido algo de éxito usando SelectFPR con Xgboost y la API de sklearn para reducir el FPR para XGBoost a través de la selección de características, luego afinando el scale_pos_weight entre 0 y 1.0. O.9 parece funcionar bien, pero como con cualquier cosa, YMMV dependiendo de sus datos. También puedes ponderar cada punto de datos individualmente cuando lo envíes a XGboost si miras sus documentos. Tienes que usar su API y no el wrapper de sklearn. De esta manera, puedes ponderar un conjunto de puntos de datos mucho más alto que el otro, y esto afectará al algoritmo de refuerzo que utiliza.

0voto

Bikash Joshi Puntos 1

Yo también me encontré con este dilema y sigo buscando la mejor solución. Sin embargo, le sugiero que utilice métodos como Grid Search (GridSearchCV en sklearn) para el mejor ajuste de los parámetros de su clasificador. Sin embargo, si su conjunto de datos está muy desequilibrado, vale la pena considerar los métodos de muestreo (especialmente el sobremuestreo aleatorio y los métodos de sobremuestreo SMOTE) y el conjunto de modelos en muestras de datos con diferentes proporciones de ejemplos de clase positivos y negativos. Aquí hay un bonito y útil tutorial (casi completo) sobre el manejo de conjuntos de datos desequilibrados.

https://www.analyticsvidhya.com/blog/2017/03/imbalanced-classification-problem/

i-Ciencias.com

I-Ciencias es una comunidad de estudiantes y amantes de la ciencia en la que puedes resolver tus problemas y dudas.
Puedes consultar las preguntas de otros usuarios, hacer tus propias preguntas o resolver las de los demás.

Powered by:

X