python - compute_class_weight - ¿Cómo funciona el parámetro class_weight en scikit-learn?
class_weight compute_class_weight example (1)
Tengo muchos problemas para entender cómo funciona el parámetro class_weight en la Regresión logística de scikit-learn.
La situación
Quiero usar la regresión logística para hacer una clasificación binaria en un conjunto de datos muy desequilibrado. Las clases están etiquetadas como 0 (negativo) y 1 (positivo) y los datos observados están en una proporción de aproximadamente 19: 1 con la mayoría de las muestras con resultado negativo.
Primer intento: preparar manualmente los datos de entrenamiento
Dividí los datos que tenía en conjuntos disjuntos para entrenamiento y pruebas (aproximadamente 80/20). Luego, muestreé al azar los datos de entrenamiento a mano para obtener datos de entrenamiento en diferentes proporciones que 19: 1; de 2: 1 -> 16: 1.
Luego entrené la regresión logística en estos diferentes subconjuntos de datos de entrenamiento y recordé el trazado (= TP / (TP + FN)) en función de las diferentes proporciones de entrenamiento. Por supuesto, el retiro se calculó en las muestras de TEST disjuntas que tenían las proporciones observadas de 19: 1. Tenga en cuenta que, aunque entrené los diferentes modelos en diferentes datos de entrenamiento, calculé el recuerdo de todos ellos en los mismos datos de prueba (disjuntos).
Los resultados fueron los esperados: el retiro fue de alrededor del 60% en proporciones de entrenamiento 2: 1 y cayó bastante rápido cuando llegó a 16: 1. Hubo varias proporciones 2: 1 -> 6: 1 donde el retiro fue decentemente superior al 5%.
Segundo intento: búsqueda de cuadrícula
A continuación, quería probar diferentes parámetros de regularización, por lo que utilicé GridSearchCV e hice una cuadrícula de varios valores del parámetro
C
, así como el parámetro
class_weight
.
Para traducir mis proporciones n: m de muestras de entrenamiento negativas: positivas al lenguaje del diccionario de
class_weight
, pensé que solo especifico varios diccionarios de la siguiente manera:
{ 0:0.67, 1:0.33 } #expected 2:1
{ 0:0.75, 1:0.25 } #expected 3:1
{ 0:0.8, 1:0.2 } #expected 4:1
y también incluí
None
y
auto
.
Esta vez los resultados fueron totalmente impactados.
Todos mis retiros salieron pequeños (<0.05) para cada valor de
class_weight
excepto
auto
.
Así que solo puedo suponer que mi comprensión de cómo configurar el diccionario
class_weight
es incorrecta.
Curiosamente, el valor
class_weight
de ''auto'' en la búsqueda de la cuadrícula fue de alrededor del 59% para todos los valores de
C
, y supongo que se equilibra a 1: 1.
Mis preguntas
1) ¿Cómo utiliza correctamente
class_weight
para lograr diferentes equilibrios en los datos de entrenamiento de lo que realmente le da?
Específicamente, ¿qué diccionario paso a
class_weight
para usar n: m proporciones de muestras de entrenamiento negativas: positivas?
2) Si pasa varios diccionarios
class_weight
a GridSearchCV, durante la validación cruzada, ¿reequilibrará los datos del pliegue de entrenamiento de acuerdo con el diccionario pero usará las proporciones de muestra verdaderas dadas para calcular mi función de puntaje en el pliegue de prueba?
Esto es crítico ya que cualquier métrica solo es útil para mí si proviene de datos en las proporciones observadas.
3) ¿Qué hace el valor
auto
de
class_weight
en cuanto a proporciones?
Leí la documentación y supongo que "equilibra los datos de forma inversamente proporcional a su frecuencia" solo significa que es 1: 1.
¿Es esto correcto?
Si no, ¿alguien puede aclarar?
Muchas gracias, cualquier aclaración sería muy apreciada!
En primer lugar, puede que no sea bueno ir solo por recuerdo. Simplemente puede lograr un retiro del 100% clasificando todo como la clase positiva. Por lo general, sugiero usar AUC para seleccionar parámetros y luego encontrar un umbral para el punto de operación (digamos un nivel de precisión dado) que le interese.
Para
class_weight
cómo funciona
class_weight
: penaliza los errores en las muestras de
class[i]
con
class_weight[i]
lugar de 1. Por lo tanto, un mayor peso de clase significa que desea poner más énfasis en una clase.
Por lo que dice, parece que la clase 0 es 19 veces más frecuente que la clase 1. Por lo tanto, debe aumentar el
class_weight
de clase de la clase 1 en relación con la clase 0, digamos {0: .1, 1: .9}.
Si
class_weight
no suma 1, básicamente cambiará el parámetro de regularización.
Para
class_weight="auto"
cómo funciona
class_weight="auto"
, puede echar un vistazo a
esta discusión
.
En la versión de desarrollo, puede usar
class_weight="balanced"
, que es más fácil de entender: básicamente significa replicar la clase más pequeña hasta que tenga tantas muestras como en la más grande, pero de manera implícita.