Tratamiento de clases desbalanceadas
20 enero 2020La presencia de clases desbalanceadas es el día a día de la mayoría de científicos de datos. Este hecho es algo que ocurre muy a menudo en problemas de clasificación donde hay una diferencia muy grande entre el número de elementos de cada clase. El desbalanceo de clases aparece en entornos variados como pueden ser la detección de fraude, enfermedades o spam.
Por suerte todos estos fenómenos, que originan que en los datos aparezcan clases muy dispares en cuanto a número de elementos, raramente ocurren.
Supongamos que quisiésemos predecir las transacciones fraudulentas en un banco. Quizás tuviésemos sólo una transacción fraudulenta entre un total de 1000. Si programásemos un modelo estadístico maximizando la accuracy (porcentaje de aciertos totales), el modelo podría predecir todas las transacciones como no fraudulentas. Nos devolvería una accuracy de 99.9 %, lo cual nos podría parecer una métrica bastante buena.
Sin embargo, analizando un poco, nos daríamos cuenta de que el modelo no predice bien. Realmente lo que nos importaba era predecir las transacciones fraudulentas correctamente, no las no fraudulentas.
¿Entonces Álvaro, qué podemos hacer en estos casos?
Métodos para tratar con clases desbalanceadas
No está todo perdido, existen una serie de procedimientos que podemos usar para predecir correctamente esas clases minoritarias poco representadas en nuestros datos. Alguno de los métodos consisten en cambiar los datos o la métrica a evaluar:
- Cambiar la métrica de evaluación: podemos usar métricas que tengan más en cuenta los datos de las clases minoritarias como son la f1, la sensitividad o la precisión.
- Muestrear: básicamente hay dos técnicas comúnmente aceptadas.
- La primera es el sobremuestreo de la clase minoritaria: consiste en añadir copias de la clase minoritaria para aumentar su peso sobre el total.
- La segunda es el submuestreo de la clase mayoritaria: se basa en quitar muestra de la clase mayoritaria para intentar equilibrar el número de muestras en cada clase.
- Generación de muestras sintéticas: en este caso, utilizando algoritmos como el SMOTE, somos capaces de generar más muestras de la clase minoritaria a partir de las que ya tenemos.
Por otro lado, existen otros métodos que suelo usar bastante aunque no sean tan comunes como los anteriores. Son métodos que dependen del modelo estadístico a utilizar:
- Usar algoritmos de Boosting: estos modelos por definición suelen centrarse en mejorar los errores que cometen. Por ejemplo, en un XGBoost, aumentando el número de árboles, podemos ir corrigiendo los errores de los árboles anteriores.
- Darle más peso a las muestras de la clase minoritaria: algoritmos como la regresión logística permiten ponderar en mayor medida los elementos según la clase que sean. Dándole mayor peso a los elementos de la clase minoritaria se centrará en ajustarse mejor a esa clase y, de este modo, predecir mejor.
- Usar algoritmos de Stacking y algoritmos de aprendizaje por refuerzo: del mismo modo que los Boosting, estos algoritmos permiten ir mejorando los aciertos de la clase minoritaria.
Desde mi experiencia personal creo que es bueno probar distintos métodos y decidir cuál se ajusta más a nuestro problema.
¿Usas algún otro método cuando tratas con clases desbalanceadas? Coméntanoslo! 😀
Si te ha sido de utilidad este post, te agradecería que me apoyases en Patreon (donando una cantidad aunque sea poca ya sea una vez, o apoyándome mensualmente). Tener una web, dominio, hosting, no es gratis y me apoyas a seguir ayudando con la difusión de educación libre. Apóyame en Patreon! Mil gracias!!
¿Te ha parecido útil este artículo?
Buenas tardes Alvaro,
Hasta que porcentaje de desbalanceo se pude aplicar las técnicas mencionadas. Por ejemplo si la clase dominante representa el 99.5% y la clase a predecir es 0.5%, es viable aplicar alguna técnica de balanceo?.
Saludos
Ben día Álvaro.
Tengo datos desbalanceado y con cuatro clases. Sin balancear el accuracy es 0.83. Usé el algoritmo SMOTE para balancear logro un accuracy 0.69. Me parece muy bajo, quizás conoce alguna otra manera.
Probé con dos modelos:
LR_base = LogisticRegression(C=1.0,penalty=’l2′,random_state=1,solver=»newton-cg», class_weight=»balanced»)
KNN_base = KNeighborsClassifier(n_neighbors=5, metric=»cosine»)
Gracias