Python & Data Science

Curvas de calibración: cuando las probabilidades de tu modelo te mienten

1. La trampa de las probabilidades: por qué la confianza de tu modelo es falsa

Imagina que estás construyendo un modelo para predecir si un solicitante de préstamo incumplirá el pago. Tu modelo analiza una nueva solicitud y dice que hay una probabilidad del 90% de pago exitoso. Te sientes genial. Apruebas el préstamo.

Pero aquí está el detalle: ¿qué pasaría si, entre todas las personas a las que tu modelo les dio una “probabilidad del 90%”, solo el 60% pagó en realidad? Entonces tu modelo no solo está equivocado. Es sobreconfiado — afirma una certeza que no puede respaldar.

La mayoría de nosotros nos enfocamos en la Exactitud (¿con qué frecuencia el modelo acierta?) o el AUC (¿qué tan bien ordena a las personas?). A menudo olvidamos la Calibración. La calibración tiene que ver con la honestidad. Si un meteorólogo dice que hay un 70% de probabilidad de lluvia todos los días durante un mes, debería llover exactamente 21 de esos 30 días. Si solo llueve 10 días, el meteorólogo está mal calibrado.

Veamos qué sucede cuando un modelo estándar nos “miente”.

import numpy as np
import pandas as pd
from sklearn.datasets import make_classification
from sklearn.ensemble import RandomForestClassifier
from sklearn.model_selection import train_test_split

# Create a fake dataset
X, y = make_classification(n_samples=10000, n_features=20, n_informative=2, n_redundant=10, random_state=42)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# Train a Random Forest
model = RandomForestClassifier(random_state=42)
model.fit(X_train, y_train)

# Get probabilities for the positive class
probs = model.predict_proba(X_test)[:, 1]

# Look at cases where the model is very confident ( > 90%)
high_conf_mask = probs > 0.9
actual_rate = y_test[high_conf_mask].mean()
print(f"When the model says >90% probability, the actual success rate is: {actual_rate:.2%}")
# Output: When the model says >90% probability, the actual success rate is: 84.21%

Lo que esto significa es que nuestro modelo es sobreconfiado. Dice “90% seguro”, pero la realidad está más cerca del 84%. En dominios de alto riesgo como la banca o la medicina, esa brecha del 6% puede ser la diferencia entre la ganancia y el desastre.

2. La calibración en una frase: lo que realmente estamos midiendo

La calibración es una prueba de realidad para tu modelo. Para medirla, agrupamos las predicciones en cubos.

Todo lo que el modelo predijo entre 0% y 10% va al Cubo A. Luego, de 10% a 20% al Cubo B, y así sucesivamente. Para cada cubo, calculamos el porcentaje real de resultados positivos.

Si el modelo está perfectamente calibrado, la probabilidad promedio predicha en el cubo debería ser igual a la fracción real de positivos. Así que vamos a calcularlo manualmente.

# Create bins
bins = np.linspace(0, 1, 11)
df = pd.DataFrame({'pred': probs, 'actual': y_test})
df['bin'] = pd.cut(df['pred'], bins)

# Calculate the average prediction vs actual outcome per bin
calibration_data = df.groupby('bin', observed=True).agg({'pred': 'mean', 'actual': 'mean'})
print(calibration_data)

La salida tiene una columna pred (lo que el modelo pensó) y una columna actual (lo que realmente ocurrió). Si pred es 0.75 y actual es 0.60, el modelo está prometiendo demasiado.

3. La curva de calibración: cómo leer el gráfico

En lugar de examinar tablas sin procesar, trazamos una Curva de calibración (también llamada Diagrama de confiabilidad).

  • La línea diagonal: La línea “Perfectamente calibrada”. Un modelo que se ubica aquí es 100% honesto.
  • Debajo de la diagonal: El modelo está sobreconfiado. Dice 80%, pero la verdad es 60%.
  • Por encima de la diagonal: El modelo está subconfiado. Dice 20%, pero la verdad es 40%.
import matplotlib.pyplot as plt
from sklearn.calibration import calibration_curve

prob_true, prob_pred = calibration_curve(y_test, probs, n_bins=10)

plt.plot(prob_pred, prob_true, marker='o', label='Random Forest')
plt.plot([0, 1], [0, 1], linestyle='--', label='Perfectly Calibrated')
plt.xlabel('Mean Predicted Probability')
plt.ylabel('Fraction of Positives')
plt.legend()
plt.show()

La curva de Random Forest suele tener forma de “S”. Demasiado cautelosa cerca del centro, demasiado extrema en los extremos.

4. ¿Por qué mienten los modelos? Causas comunes de descalibración

¿Por qué no todos los modelos simplemente dicen la verdad?

  1. Diseño del algoritmo: La regresión logística maximiza la verosimilitud de los datos, lo que naturalmente produce probabilidades bien calibradas. Los bosques aleatorios toman un camino diferente: promedian los votos. Si 90 de 100 árboles eligen “Clase A”, obtienes 0.9. Pero esos árboles están correlacionados, por lo que ese “90%” no es una verdadera probabilidad estadística.
  2. Sobreajuste: Cuando un modelo memoriza el ruido en los datos de entrenamiento, se vuelve excesivamente “seguro” de sus decisiones, empujando las probabilidades hacia 0 o 1.
  3. Datos desbalanceados: Si solo el 1% de tus datos pertenece a la clase positiva, los modelos tienen dificultades para encontrar la “línea base” adecuada para su nivel de confianza.

5. Cómo solucionarlo: métodos de calibración que realmente funcionan

Las buenas noticias: no tienes que reentrenar todo tu modelo. Un paso de posprocesamiento hace el trabajo.

Dos enfoques principales corrigen un modelo que miente:

  1. Platt Scaling: Entrena una pequeña regresión logística sobre las salidas de tu modelo. Aprende a “estirar” o “comprimir” las probabilidades de vuelta a la realidad.
  2. Isotonic Regression: Más flexible: ajusta una línea no decreciente a los datos. Funciona bien con una gran cantidad de ejemplos, pero puede sobreajustarse en muestras pequeñas.
from sklearn.calibration import CalibratedClassifierCV

# Platt Scaling (method='sigmoid')
calibrated_platt = CalibratedClassifierCV(model, method='sigmoid', cv='prefit')
calibrated_platt.fit(X_test, y_test) # Usually you use a separate validation set here!

# Isotonic Regression
calibrated_iso = CalibratedClassifierCV(model, method='isotonic', cv='prefit')
calibrated_iso.fit(X_test, y_test)

# Let's see the improvement
probs_platt = calibrated_platt.predict_proba(X_test)[:, 1]
prob_true_platt, prob_pred_platt = calibration_curve(y_test, probs_platt, n_bins=10)

plt.plot(prob_pred_platt, prob_true_platt, marker='s', label='Platt Scaled')
plt.plot([0, 1], [0, 1], linestyle='--')
plt.legend()
plt.show()

6. Cuándo calibrar (y cuándo no)

¿Siempre necesitas hacer esto? No.

La calibración importa si:

  • Tomas decisiones basadas en un umbral (p. ej., “Solo llamar a los clientes con un riesgo de fuga >15%”).
  • Calculas el valor esperado (p. ej., “Probabilidad de venta * Precio”).
  • Combinas múltiples modelos.

La calibración no importa si:

  • Solo te importa el ranking. Si solo necesitas saber quién tiene más probabilidad de comprar que otra persona, la probabilidad exacta no cambiará ese orden.

7. Integrando todo: un flujo de trabajo real

En un proyecto real, querrás tres particiones de datos: Entrenamiento para construir el modelo, Calibración para ajustar las probabilidades, y Prueba para ver cómo te fue en realidad.

# 1. Split data
X_temp, X_test, y_temp, y_test = train_test_split(X, y, test_size=0.2)
X_train, X_calib, y_train, y_calib = train_test_split(X_temp, y_temp, test_size=0.2)

# 2. Train model
rf = RandomForestClassifier().fit(X_train, y_train)

# 3. Calibrate on the calibration set
calibrator = CalibratedClassifierCV(rf, cv='prefit', method='isotonic')
calibrator.fit(X_calib, y_calib)

# 4. Evaluate on the final test set
final_probs = calibrator.predict_proba(X_test)[:, 1]

8. El inconveniente: la calibración no es magia

Aquí está la dura verdad: la calibración no hace que tu modelo sea más inteligente.

Un modelo con un AUC bajo que no puede distinguir los buenos préstamos de los malos sigue igual después de la calibración. Lo que obtienes es un modelo “honestamente malo”. En lugar de dar la respuesta incorrecta con confianza, te dice: “No estoy seguro, es más o menos un 50/50 de probabilidad.”

Cabe destacar: calibrar con un conjunto de datos minúsculo puede significar ajustarse al ruido. Siempre verifica tu calibración con datos nuevos.

9. Siguientes pasos: calibración en producción

Los datos del mundo real cambian. Eso es deriva de conceptos. Un modelo perfectamente calibrado en enero puede volverse demasiado confiado para junio a medida que cambia el comportamiento del cliente.

Para manejar esto:

  1. Monitorea el ECE: Realiza un seguimiento del Error de Calibración Esperado — la brecha promedio entre la curva y la diagonal.
  2. Recalibra con frecuencia: No siempre es necesario reentrenar el pesado Random Forest. A veces, actualizar solo el Platt Scaling (la regresión logística en la parte superior) es suficiente para corregir la deriva.

Resumen:

  • La exactitud te dice si el modelo está en lo correcto; la calibración te dice si sabe cuándo está en lo correcto.
  • Usa calibration_curve para visualizar qué tan honesto es tu modelo.
  • Usa CalibratedClassifierCV para corregir modelos demasiado confiados o poco confiados.
  • La calibración es importante para la gestión de riesgos y las decisiones financieras.

Comprueba tu comprensión

Las preguntas a continuación avanzan desde la simple memorización hasta el diseño abierto, siguiendo aproximadamente la Taxonomía de Bloom.

Recordar ¿Qué significa que un modelo sea “sobreconfiado” frente a “subconfiado” en una curva de calibración, en relación con la línea diagonal?

Comprender Con tus propias palabras, explica por qué los Random Forests tienden a estar peor calibrados que la regresión logística, utilizando la explicación del artículo sobre cómo cada algoritmo produce su probabilidad.

Aplicar Utilizando la lógica de agrupación (buckets) del artículo (probabilidad predicha promedio frente a tasa positiva real), si un grupo de predicciones tiene una probabilidad predicha promedio de 0.75 pero la tasa positiva real en ese grupo es 0.55, ¿el modelo es sobreconfiado o subconfiado para ese grupo, y por cuántos puntos porcentuales?

Analizar El artículo dice que la calibración “no hace que tu modelo sea más inteligente”: un modelo con un AUC bajo simplemente se vuelve “honestamente malo” en lugar de estar confiado y equivocado. Explica por qué corregir la calibración (un paso de procesamiento posterior sobre las probabilidades) no puede mejorar la capacidad de un modelo para ordenar los buenos préstamos por encima de los malos, a pesar de que cambia los números reales de las probabilidades.

Evaluar La Sección 7 del artículo recomienda una división en tres partes: Entrenamiento, Calibración y Prueba. Critica el código de la Sección 5, que en su lugar calibra y evalúa CalibratedClassifierCV en el mismo X_test/y_test. ¿Qué falla específicamente en una curva de calibración que se grafica utilizando los mismos datos con los que se ajustó el calibrador?

Crear Diseña un plan de monitoreo para la deriva de calibración en producción para un modelo de riesgo crediticio: ¿qué rastrearías (haciendo referencia a la idea de “Error de Calibración Esperado” del artículo), con qué frecuencia lo revisarías y qué desencadenaría una recalibración frente a un reentrenamiento completo del modelo?

Esta traducción fue generada automáticamente y puede contener errores. Si el idioma inglés es tu preferencia, puedes leer el artículo original en inglés .

«Aplica lo que aprendiste» es para suscriptores Supporter e Insider.

Suscríbete para desbloquear los ejercicios de este artículo.

Ver planes

¿Buscas otra cosa?

Busca en todos los artículos por título, resumen o tema.