Clases desbalanceadas en modelos de Machine Learning

Inteligencia Artificial en Salud

Clases desbalanceadas en modelos de Machine Learning

Clases desbalanceadas en modelos de Machine Learning

(Imbalanced data)

Cuando utilizamos modelos de machine Learning para fines de clasificación,  corremos el riesgo de encontrarnos con clases desbalanceadas (imbalanced data) .  Por ejemplo cuando tenemos que etiquetar   «spam» o «no spam» ó entre múltiples categorías (Medicamento 1, 2 o 3) es frecuente encontrar que en nuestro conjunto de datos de entrenamiento contamos con que alguna de las clases de la muestra es una clase «minoritaria» es decir, de la cual tenemos muy pocos casos . Esto provoca un desbalanceo en los datos que utilizaremos para el entrenamiento de nuestra máquina. Además el problema es que al final de cuentas, nuestro algoritmo será muy bueno detectando las clases mayoritarias, pero muy malo detctando las minoritarias , lo que nos puede acarrerar muchos errores tipo 1, (Falsos Positivos).  Hablaremos un poco entonces sobre Clases desbalanceadas en modelos de Machine Learning (Imbalanced data)

Un caso muy evidente es en el área de Salud en donde solemos encontrar conjuntos de datos con miles de registros con pacientes «negativos» y unos pocos casos positivos es decir, que padecen la enfermedad que queremos clasificar.

Otros ejemplos suelen ser los de detección de fraude en las tarjetas de crédito, donde tenemos muchas muestras de clientes «honestos» y pocos casos etiquetados como fraudulentos.

¿Cómo nos afectan las Clases desbalanceadas en modelos de Machine Learning ?

Por lo general nos en su proceso de “generalización de la información” (aplicar el conocimiento a casos nuevos )  y perjudicando a las clases minoritarias. Esto suena bastante razonable: si a una red neuronal le damos 990 de fotos de gatitos y sólo 10 de perros, no podemos pretender que logre diferenciar una clase de otra. Lo más probable que la red se limite a responder siempre «tu foto es un gato» puesto que así tuvo un acierto del 99% en su fase de entrenamiento.

Veamoslo con un ejemplo utilizando Python y Anaconda

Primero, usaremos el set de datos Credit Card Fraut Detection de la web de Kaggle. Son 66 MB que al descomprimir ocuparán unos 150MB. Usaremos el archivo creditcard.csv. Este set de datos tiene 285.000 filas (casos)  con 31 columnas (atributos o features). Como la información es privada, no sabemos realmente que significan los atributos  y están nombradas como V1, V2, V3, etc. excepto por las columnas Time y Amount (el importe de la transacción). Hay además una columna que clasifica la transacción, con 0 y 1 dependiendo si fue una «transacción Normal» ó si «Hubo Fraude». Como podrán ver , el set de datos está muy desequilibrado y tendremos muy pocas muestras etiquetadas como fraude.

Pero nos centraremos entonces en  aplicar las diversas estrategias para mejorar los resultados, si lo que queremos es que nuestro modelo clasifique de forma adecuada.

Requerimientos Técnicos

Sin embargo, la recomendación es tener instalado el ambiente de trabajo Anaconda Navigator, con Python 3.6 y la librería “Imbalanced Learn” . Ingresamos al Jupyter Notebooks y  desde linea de el comandos tendremos que instalar esta librería:

pip install unbalanced data

Análisis exploratorio, para comprobar el desequilibrio entre las clases.

En este primer bloque de programa, instalaremos todas las librerías que podríamos necesitar para nuestro ejercicio.

Por ejemplo:

Pero luego de importar las librerías, cargamos nuestros datos y luego exploramos el dataframe

df = pd.read_csv(“creditcard.csv”) # (leyendo los datos)
df.head(n=5)  (desplegar encabezados de los primeros 5 casos

Veamos de cuantas filas tenemos y cuantas hay de cada clase:

(284807, 31)

0 284315
1 492
Name: Class, dtype: int64

Además vemos que son 284.807 filas y solamente 492 son la clase minoritaria, que en este caso son los casos de fraude, y que apenas representan el 0,17% del total de muestras.

¿Llegas a ver la mínima linea roja que representa los casos de Fraude? son muy pocas muestras!

Estrategias para el manejo de Clases  Desbalanceadas:

Así que, tenemos diversas estrategias para tratar de mejorar la situación. Las comentaremos brevemente y pasaremos a describirlas una por una

  1. Ajuste de Parámetros del modelo:

    En resumen consiste en ajustar parametros ó metricas del propio algoritmo para intentar equilibrar a la clase minoritaria,  penalizando a la clase mayoritaria durante el entrenamiento. Ejemplos en ajuste de peso en árboles, también en logistic regression tenemos el parámetro class_weight= «balanced» que utilizaremos en este ejemplo. Además no todos los algoritmos tienen estas posibilidades. En redes neuronales por ejemplo podríamos ajustar la métrica de Loss, y asi penalizar las clases mayoritarias.

  2. Modificar el Dataset:

    Por ejemplo, podemos eliminar muestras de la clase mayoritaria para reducirlo e intentar equilibrar la situación. Tiene como «peligroso» que podemos prescindir de muestras importantes, que brindan información y por lo tanto empeorar el modelo. Entonces para seleccionar qué muestras eliminar, deberíamos seguir algún criterio. También podríamos agregar nuevas filas con los mismos valores de las clases minoritarias, por ejemplo cuadriplicar nuestras 492 filas. Pero esto no sirve demasiado y podemos llevar al modelo a caer en overfitting.

  3. Muestras artificiales:

    Primero podemos intentar crear muestras sintéticas (no idénticas) utilizando diversos algoritmos que intentan seguir la tendencia del grupo minoritario. Según el método, podemos mejorar los resultados. Lo peligroso de crear muestras sintéticas es que podemos alterar la distribución «natural» de esa clase y confundir al modelo en su clasificación.

  4. Balanced Ensemble Methods:

    Utiliza las ventajas de hacer ensamble de métodos, es decir, entrenar diversos modelos y entre todos obtener el resultado final (por ejemplo «votando») pero se asegura de tomar muestras de entrenamiento equilibradas.

Apliquemos estas técnicas de a una a nuestro código y veamos los resultados.

PERO… antes de empezar, ejecutaremos el modelo de Regresión Logística «desequilibrado», para tener un punto de partida, es decir unas métricas contra las cuales podremos comparar y ver si estamos mejorando.

Probando el Modelo ( primero,  sin ninguna estrategia de corrección)

Por ejemplo, aquí vemos en  la matriz de confusión , la clase 2 (Es la clase que nos interesa detectar ) hay  51 fallos y 97 aciertos. Esto representa un  recall de 0.66 y es el valor que queremos mejorar. También es interesante notar que en la columna de f1-score obtenemos muy buenos resultados PERO que realmente no nos deben engañar… pues están reflejando una realidad parcial. Lo cierto es que nuestro modelo no es capaz de detectar correctamente los casos de Fraude.

1.) Estrategia: Compensación por penalización

Sobre todo utilizaremos un parámetro adicional en el modelo de Regresión logística en donde indicamos weight = «balanced» y con esto,  el algoritmo se encargará de equilibrar a la clase minoritaria durante el entrenamiento.

Por ejemplo:

Sobre todo vemos una NOTABLE MEJORA! en la clase 2 -que indica si hubo fraude-, se han acertado 137 muestras y fallado en 11, dando un recall de 0.93 !! (esto con sólamente  agregar un parámetro al modelo)

También notemos que en la columna de f1-score parecería que hubieran «empeorado» los resultados… cuando realmente estamos mejorando la detección de casos fraudulentos. Es cierto que aumentan los Falsos Positivos y se han etiquetado 1890 muestras como Fraudulentas cuando no lo eran… pero ustedes piensen… ¿qué prefiere la compañía bancaria? ¿tener que revisar esos casos manualmente ó fallar en detectar los verdaderos casos de fraude?

Como resultado sigamos con más métodos:

2.) Estrategia: Hacer submuestreo en la clase mayoritaria

Primero, lo que haremos es utilizar un algoritmo para reducir la clase mayoritaria. Lo haremos usando un algoritmo que hace similar al k-nearest neighbor (vecino mas cercano)  para ir seleccionando cuales eliminar.

Mientras tanto fijemonos que reducimos bestialmente de 199.020 muestras de clase cero (la mayoría) y pasan a ser 688. y Con esas muestras entrenamos el modelo.

Distribution before resampling Counter({0: 199020, 1: 344})
Distribution after resampling Counter({0: 688, 1: 344})

También vemos que obtenemos muy buen resultado con un recall de 0.93, pero a costa de que aumentaron los falsos positivos.

3.) Estrategia: Oversampling de la clase minoritaria

En este caso, crearemos muestras nuevas «sintéticas» de la clase minoritaria. Usando RandomOverSampler. Y vemos que pasamos de 344 muestras de fraudes a 99.510.

Tenemos un 0.89 de recall para la clase 2 y los Falsos positivos son 838. Nada mal.

4.) Estrategia: Combinando resampling con Smote-Tomek

En otras palabras ahora probaremos una técnica muy usada que consiste en aplicar en simultáneo un algoritmo de subsampling y otro de oversampling a la vez al dataset. En este caso usaremos SMOTE para oversampling: busca puntos vecinos cercanos y agrega puntos «en linea recta» entre ellos. Y usaremos Tomek para undersampling que quita los de distinta clase que sean nearest neighbor y deja ver mejor el decisión boundary (la zona limítrofe de nuestras clases).

Mientras tanto seguimos teniendo bastante buen recall 0.85 de la clase 2 y vemos que los Falsos positivos de la clase 1 son bastante pocos, 325 (de 85295 muestras).

5.) Estrategia: Ensamble de Modelos con Balanceo

Para esta estrategia usaremos un Clasificador de Ensamble ( Bagging o empaquetamiento ) y el modelo será un DecisionTree. Veamos como se comporta:

Tampoco está mal. Vemos siempre mejora con respecto al modelo inicial con un recall de 0.88 para los casos de fraude.

Resultados de las Estrategias

Veamos en una tabla, ordenada de mejor a peor los resultados obtenidos.

Sin embargo, vemos que en nuestro caso las estrategias de Penalización y Subsampling nos dan el mejor resultado, cada una con un recall de 0.93.

Pero quedémonos con esto: Con cualquiera de las técnicas que aplicamos MEJORAMOS el modelo inicial de Regresión logística, que lograba solo un un 0.66 de recall para la clase de Fraude.

IMPORTANTE: esto no quiere decir que siempre hay que aplicar Penalización ó NearMiss Subsampling!, dependerá del caso, del desbalanceo y del modelo (en este caso usamos regresión logística, pero podría ser otro!).

Conclusiones

Además es muy frecuente encontrarnos clases desbalanceadas en modelos de Machine Learning, de hecho… lo más raro sería encontrar datasets bien equilibrados.

Una pregunta frecuente es o «¿Que hacer cuando tengo pocas muestras de una clase?». Mi primera respuesta y la de sentido común es «Sal a la calle y consigue más muestras!» pero la realidad es que no siempre es posible conseguir más datos de las clases minoritarias (como por ejemplo en Casos de Salud).

Como resultado la Matriz de Confusión es un útil instrumento para medir si las métricas pueden ser engañosas… si miramos a nuestros aciertos únicamente, puede que pensemos que tenemos un buen clasificador, cuando realmente está fallando.

El presente artículo fue adaptado de varios blogs, de mi experiencia personal pero principalmente del blog aprende machinelearning y machinelearningparatodos  y el blog de Amsantac.co

 

 

 

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

HTML Snippets Powered By : XYZScripts.com