evaluar modelos de clasificacion

Cómo evaluar modelos de clasificación en Python: una guía para principiantes

Esta guía le presenta un conjunto de métricas de rendimiento de clasificación en Python y algunos métodos de visualización que todo científico de datos debería conocer.

La clasificación de aprendizaje automático es un tipo de aprendizaje supervisado en el que un algoritmo asigna un conjunto de entradas a una salida discreta. Los modelos de clasificación tienen una amplia gama de aplicaciones en industrias dispares y son uno de los pilares del aprendizaje supervisado. La simplicidad de definir un problema hace que los modelos de clasificación sean bastante versátiles e independientes de la industria. 

Una parte importante de la construcción de modelos de clasificación es la evaluación del rendimiento del modelo. En resumen, los científicos de datos necesitan una forma confiable de probar aproximadamente qué tan bien un modelo predecirá correctamente un resultado. Hay muchas herramientas disponibles para evaluar el rendimiento del modelo; Dependiendo del problema que esté tratando de resolver, algunos pueden ser más útiles que otros. 

Por ejemplo, si tiene una representación equitativa de todos los resultados en la precisión de sus datos, entonces una matriz de confusión puede ser suficiente como métrica de rendimiento. Por el contrario, si sus datos muestran un desequilibrio, lo que significa que uno o más resultados están significativamente subrepresentados, es posible que desee utilizar una métrica como la precisión. Si desea comprender qué tan robusto es su modelo a través de los umbrales de decisión, las métricas como el área bajo la curva característica operativa del receptor (AUROC) y el área bajo la curva de recuperación de precisión (AUPRC) pueden ser más apropiadas. 

Dado que la elección de la métrica de clasificación adecuada depende de la pregunta que intenta responder, todos los científicos de datos deben estar familiarizados con el conjunto de métricas de rendimiento de clasificación. La biblioteca Scikit-Learn en Python tiene un módulo de métricas que hace que la exactitud, la precisión, el AUROC y el AUPRC de computación sean rápidos y sencillos. Además, es igualmente importante saber cómo visualizar el rendimiento del modelo a través de curvas ROC, curvas PR y matrices de confusión. 

Aquí, consideraremos la tarea de construir un modelo de clasificación simple que prediga la probabilidad de abandono de clientes. Churn se define como el evento en el que un cliente abandona una empresa, se da de baja o ya no realiza una compra después de un período de tiempo. Trabajaremos con los datos Telco Churn, que contienen información sobre una empresa de telecomunicaciones ficticia. Nuestras tareas serán predecir si el cliente dejará o no la empresa y evaluar qué tan bien nuestro modelo realiza esta tarea.

Una guía para principiantes para evaluar modelos de clasificación en Python

  • Construcción de un modelo de clasificación
  • Matrices de precisión y confusión
  • Curva ROC y AUROC
  • AUPRC

Construcción de un modelo de clasificación

Comencemos leyendo los datos de Telco Churn en un marco de datos de Pandas:

df = pd.read_csv('telco_churn.csv')

Ahora, mostremos las primeras cinco filas de datos:

df.head()
evaluación-de-clasificación-de-modelos
Imagen creada por el autor.

Vemos que el conjunto de datos contiene 21 columnas con valores categóricos y numéricos. Los datos también contienen 7043 filas, lo que corresponde a 7043 clientes únicos. 

Construyamos un modelo simple que tome la permanencia, que es la cantidad de tiempo que el cliente ha estado con la empresa, y MonthlyCharges como entradas y predice la probabilidad de que el cliente abandone. El resultado será la columna Churn, que tiene un valor de sí o no. 

Primero, modifiquemos nuestra columna de destino para tener valores binarios legibles por máquina. Le daremos a la columna Churn un valor de uno para sí y cero para no. Podemos lograr esto usando el método where() de numpy:

import numpy as np 

df['Churn'] = np.where(df['Churn'] == 'Yes', 1, 0)

A continuación, definamos nuestra entrada y salida:

X = df[['tenure', 'MonthlyCharges']]

y = df['Churn']

Luego podemos dividir nuestros datos para entrenamiento y prueba. Para hacer esto, necesitamos importar el método train_test_split desde el módulo model_selection en Sklearn. Generemos un conjunto de entrenamiento que constituya el 67 por ciento de nuestros datos y luego usemos los datos restantes para la prueba. El conjunto de prueba se compone de 2325 puntos de datos:

from sklearn.model_selection import train_test_split

X_train, X_test, y_train, y_test = train_test_split(X, y,

test_size=0.33, random_state=42)

Para nuestro modelo de clasificación, usaremos un modelo de regresión logística simple. Importemos la clase LogisticRegression del módulo linear_models en Sklearn:

from sklearn.linear_models import LogisticRegression

Ahora, definamos una instancia de nuestra clase de regresión logística y almacenémosla en una variable llamada clf_model. Luego ajustaremos nuestro modelo a nuestros datos de entrenamiento:

clf_model = LogisticRegression()

clf_model.fit(X_train, y_train)

Finalmente, podemos hacer predicciones sobre los datos de prueba y almacenar las predicciones en una variable llamada y_pred:

y_pred = cllf_model.predict(X_test)

Ahora que hemos entrenado nuestro modelo y hecho predicciones sobre los datos de prueba, necesitamos evaluar qué tan bien funcionó nuestro modelo. 

Relacionado: Una guía para principiantes sobre la disputa de datos de texto con Pandas en Python

Matrices de precisión y confusión 

Una métrica de rendimiento simple y ampliamente utilizada es la precisión. Este es simplemente el número total de predicciones correctas dividido por el número de puntos de datos en el conjunto de prueba.

Podemos importar el método precision_score desde el módulo métrico en Sklearn y calcular la precisión. El primer argumento de precision_score son las etiquetas reales, que se almacenan en y_test. El segundo argumento es la predicción, que se almacena en y_pred:

from sklearn.metrics import accuracy_score

print("Accuracy: ", accuracy_score(y_test, y_pred))
evaluación-de-clasificación-de-modelos
Imagen creada por el autor.

Vemos que nuestro modelo tiene una precisión de predicción del 79 por ciento. Aunque esto es útil, en realidad no sabemos mucho acerca de qué tan bien nuestro modelo predice específicamente la rotación o la ausencia de rotación. Las matrices de confusión pueden brindarnos un poco más de información sobre qué tan bien funciona nuestro modelo para cada resultado. 

Es importante tener en cuenta esta métrica si sus datos están desequilibrados. Por ejemplo, si nuestros datos de prueba tienen 95 etiquetas de no abandono y cinco etiquetas de abandono, al adivinar «no abandono» para cada cliente, puede dar una precisión engañosa del 95 por ciento. 

Ahora generaremos una matriz de confusión a partir de nuestras predicciones. Importemos el paquete de matriz de confusión del módulo de métricas en Sklearn:

from sklearn.metrics import confusion_matrix

Generemos nuestra matriz de confusión y almacenémosla en una variable llamada conmat:

conmat = confusion_matrix(y_test, y_pred)

Vamos a crear un marco de datos a partir de la matriz de matriz de confusión, llamado df_cm:

val = np.mat(conmat) 

classnames = list(set(y_train))

df_cm = pd.DataFrame(

        val, index=classnames, columns=classnames, 

    )

print(df_cm)
evaluación-de-clasificación-de-modelos
Imagen creada por el autor.

Ahora, generemos nuestra matriz de confusión usando el método de mapa de calor de Seaborn:

import matplotlib.pyplot as plt

import seaborn as sns

plt.figure()

heatmap = sns.heatmap(df_cm, annot=True, cmap="Blues")

heatmap.yaxis.set_ticklabels(heatmap.yaxis.get_ticklabels(), rotation=0, ha='right')

heatmap.xaxis.set_ticklabels(heatmap.xaxis.get_ticklabels(), rotation=45, ha='right')

plt.ylabel('True label')

plt.xlabel('Predicted label')

plt.title('Churn Logistic Regression Model Results')

plt.show()    
evaluación-de-clasificación-de-modelos
Imagen creada por el autor.

Entonces, ¿qué nos dice exactamente esta cifra sobre el rendimiento de nuestro modelo? Mirando a lo largo de la diagonal de la matriz de confusión, prestemos atención a los números 1553 y 289. El número 1553 corresponde a la cantidad de clientes que el modelo predijo correctamente que no abandonarían, lo que significa que se quedan en la empresa. El número 289 corresponde al número de clientes que el modelo predijo correctamente que abandonarían. 

Sería mejor si pudiéramos mostrarlos como porcentajes de un número total. Por ejemplo, sería útil saber qué porcentaje de todos los abandonos representan los 289 clientes pronosticados correctamente. Podemos mostrar porcentajes para cada resultado agregando la siguiente línea de código antes de nuestra gráfica de mapa de calor:

df_cm = df_cm.astype('float') / df_cm.sum(axis=1)[:, np.newaxis]  
evaluación-de-clasificación-de-modelos
Imagen creada por el autor.

Como podemos ver, nuestro modelo predice correctamente el 91 por ciento de los clientes que no abandonan y el 46 por ciento de los clientes que lo hacen. Esto ilustra claramente las limitaciones del uso de la precisión, ya que no nos dio información sobre el porcentaje de resultados predichos correctamente. 

Curva ROC y AUROC

A menudo, las empresas quieren trabajar con probabilidades previstas en lugar de etiquetas discretas. Esto les permite seleccionar el umbral para etiquetar un resultado como negativo o positivo. Cuando se trata de probabilidades, necesitamos una forma de medir qué tan bien se generaliza el modelo a través de los umbrales de probabilidad. Hasta este momento, a nuestro algoritmo se le han asignado etiquetas binarias utilizando un umbral predeterminado de 0,5, pero tal vez el umbral de probabilidad ideal sea mayor o menor, según el caso de uso. 

En el caso de datos balanceados, el umbral ideal es 0,5. Cuando nuestros datos están desequilibrados, el umbral ideal suele ser más bajo. Además, las empresas a veces prefieren trabajar con probabilidades en lugar de etiquetas discretas por completo. Dada la importancia de las probabilidades de predicción, es útil comprender qué métricas usar para evaluarlas.

El AUROC es una forma de medir qué tan robusto es su modelo a través de los umbrales de decisión. Es el área bajo el gráfico de la tasa de verdaderos positivos frente a la tasa de falsos positivos. La tasa de verdaderos positivos (TPR) es (verdaderos positivos)/(verdaderos positivos + falsos negativos). La tasa de falsos positivos es (falso positivo)/(falso positivo + verdadero negativo). 

En el contexto de nuestro problema de abandono, esto medirá qué tan bien nuestro modelo captura a los clientes que no abandonan a través de diferentes umbrales de probabilidad. 

Empecemos por calcular el AUROC. Importemos los métodos roc_curve y roc_auc_score desde el módulo de métricas:

from sklearn.metrics import roc_curve, roc_auc_score

A continuación, generemos probabilidades predichas en nuestro conjunto de prueba usando nuestro modelo entrenado:

y_pred_proba = clf_model.predict_proba(np.array(X_test))[:,1]

Luego podemos calcular la tasa de falsos positivos (for) y la tasa de verdaderos positivos (tpr) para diferentes umbrales de probabilidad:

fpr, tpr, thresholds = roc_curve(y_test, y_pred_proba)

Finalmente, podemos trazar nuestra curva ROC:

sns.set()

plt.plot(fpr, tpr)

plt.plot(fpr, fpr, linestyle = '--', color = 'k')

plt.xlabel('False positive rate')

plt.ylabel('True positive rate')

AUROC = np.round(roc_auc_score(y_test, y_pred_proba), 2)

plt.title(f'Logistic Regression Model ROC curve; AUROC: {AUROC}');

plt.show()
evaluación-de-clasificación-de-modelos
Imagen creada por el autor.

Cuanto más rápido se acerque a uno la tasa positiva verdadera, mejor será el comportamiento de nuestra curva ROC. Entonces, nuestro modelo funciona bastante bien en estos términos.

Además, un AUROC de 0,82 es bastante bueno ya que un modelo perfecto tendría un AUROC de 1,0. Vimos que el 91 por ciento de los casos negativos (es decir, sin abandono) fueron predichos correctamente por nuestro modelo al usar un umbral predeterminado de 0.5, por lo que esto no debería ser una sorpresa. 

AUPRC (Precisión media) 

El área debajo de la curva de recuperación de precisión nos brinda una buena comprensión de nuestra precisión en diferentes umbrales de decisión. La precisión es (verdadero positivo)/(verdadero positivo + falso positivo). Recordar es otra palabra para la verdadera tasa positiva. 

En el caso de la rotación, AUPRC (o precisión promedio) es una medida de qué tan bien nuestro modelo predice correctamente que un cliente dejará una empresa, en contraste con la predicción de que el cliente permanecerá, a través de los umbrales de decisión. Generar la curva de precisión/recuperación y calcular el AUPRC es similar a lo que hicimos para AUROC:

from sklearn.metrics import precision_recall_curve

from sklearn.metrics import average_precision_score

average_precision = average_precision_score(y_test, y_test_proba)

precision, recall, thresholds = precision_recall_curve(y_test, y_test_proba)

plt.plot(recall, precision, marker='.', label='Logistic')

plt.xlabel('Recall')

plt.ylabel('Precision')

plt.legend()

plt.title(f'Precision Recall Curve. AUPRC: {average_precision}')

plt.show()
evaluación-de-clasificación-de-modelos
Imagen creada por el autor.

Podemos ver que, con un AUPRC de 0,63 y la rápida disminución de la precisión en nuestra curva de precisión/recuperación, nuestro modelo hace un peor trabajo al predecir si un cliente se irá a medida que cambia el umbral de probabilidad. Este resultado es de esperar ya que vimos que cuando usamos un umbral predeterminado de 0.5, solo el 46 por ciento de las etiquetas de abandono se predijeron correctamente. Para aquellos interesados ​​en trabajar con los datos y el código, el script de Python está disponible aquí

Evaluación de modelos de clasificación

Los científicos de datos en todos los dominios e industrias deben tener una sólida comprensión de las métricas de rendimiento de clasificación. Saber qué métricas utilizar para datos desequilibrados o equilibrados es importante para comunicar claramente el rendimiento de su modelo. El uso ingenuo de la precisión para comunicar los resultados de un modelo entrenado en datos desequilibrados puede inducir a error a los clientes a pensar que su modelo funciona mejor de lo que realmente lo hace. 

Además, es vital tener una sólida comprensión de cómo se utilizarán las predicciones en la práctica. Puede darse el caso de que una empresa busque etiquetas de resultados discretos que pueda utilizar para tomar decisiones. En otros casos, las empresas están más interesadas en usar probabilidades para tomar sus decisiones, en cuyo caso necesitamos evaluar probabilidades. Estar familiarizado con muchos ángulos y enfoques para evaluar el rendimiento del modelo es crucial para el éxito de un proyecto de aprendizaje automático. 

El paquete Scikit-learn en Python proporciona herramientas convenientemente para la mayoría de las métricas de rendimiento que puede necesitar usar. Esto le permite obtener una vista del rendimiento del modelo desde muchos ángulos en un corto período de tiempo y relativamente pocas líneas de código. Ser capaz de generar rápidamente matrices de confusión, curvas ROC y curvas de precisión/recuperación permite a los científicos de datos iterar más rápido en los proyectos. 

Ya sea que desee crear y evaluar rápidamente un modelo de aprendizaje automático para un problema, comparar modelos de ML, seleccionar características de modelos o ajustar su modelo de aprendizaje automático, tener un buen conocimiento de estas métricas de rendimiento de clasificación es un conjunto de habilidades invaluable.