Cómo crear un calibrador de probabilidad en Machine Learning
Calibrar probabilidades en Machine Learning mejora la confianza en las predicciones de modelos de clasificación (por ejemplo, cuando un modelo indica 0.9, eso debería corresponder al 90% de ocurrencia). Este tutorial muestra cómo crear un calibrador de probabilidad en Python usando scikit-learn, explicando por qué y cómo evitar errores comunes.
Requisitos previos
- Python 3.8+ con scikit-learn instalado
- Conceptos básicos de clasificación binaria (probabilidades, métricas como ROC/AUC)
- IDE o Jupyter Notebook para ejecutar código
Paso 1: Entender por qué calibrar probabilidades
Modelos como RandomForest o SVM no siempre devuelven probabilidades bien calibradas. La salida de predict_proba refleja la confianza del modelo según su propia estructura, no necesariamente la frecuencia real observada. Calibrar ajusta las probabilidades predichas para que la frecuencia observada se aproxime a las probabilidades predichas: por ejemplo, entre las instancias donde el modelo predice ~0.8, aproximadamente el 80% deberían ser positivas.
Errores comunes: calibrar sobre los mismos datos de entrenamiento (provoca overfitting), usar Isotonic con pocos ejemplos (overfitting no paramétrico) u olvidar mantener la misma distribución de clases entre entrenamiento, calibración y prueba. En problemas con 10% de positivos, la calibración debe preservar esa estratificación — idealmente usando stratify en las particiones o validación cruzada estratificada.
Paso 2: Preparar datos de ejemplo
Use un dataset sencillo para practicar. El conjunto breast_cancer de scikit-learn tiene 569 muestras: si sigue la partición abajo (60% entrenamiento, 20% calibración, 20% prueba), tendrá aproximadamente 341 muestras para entrenamiento y 114 para calibración y prueba cada una. Tener algunas centenas de ejemplos en la fase de calibración es útil, especialmente para Isotonic.
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
X, y = load_breast_cancer(return_X_y=True)
X_train, X_temp, y_train, y_temp = train_test_split(X, y, test_size=0.4, random_state=42)
X_calib, X_test, y_calib, y_test = train_test_split(X_temp, y_temp, test_size=0.5, random_state=42)
Paso 3: Entrenar un modelo base sin calibrar
Entrene un clasificador estándar y obtenga predicciones no calibradas para servir de línea base. Aquí usamos RandomForestClassifier por ser común en problemas tabulares. Mida el Brier score como métrica de la calidad probabilística — cuanto más cercano a 0, mejor.
from sklearn.ensemble import RandomForestClassifier
from sklearn.metrics import brier_score_loss
clf = RandomForestClassifier(random_state=42)
clf.fit(X_train, y_train)
probs_uncal = clf.predict_proba(X_test)[:, 1]
print('Brier (no calibrado):', brier_score_loss(y_test, probs_uncal))
Como referencia, en un caso típico con este dataset puede ver Brier ~0.06-0.12 dependiendo de la semilla; el objetivo es reducir ese valor con calibración.
Paso 4: Calibrar con CalibratedClassifierCV (Platt e Isotonic)
scikit-learn ofrece CalibratedClassifierCV que implementa Platt scaling (método 'sigmoid') e Isotonic. Platt ajusta una regresión logística a los scores del clasificador y es paramétrico — menos susceptible a overfitting cuando la muestra de calibración es pequeña. Isotonic es no paramétrico (función monótona libre) y puede capturar relaciones más complejas si hay muchas muestras de calibración.
from sklearn.calibration import CalibratedClassifierCV
# Platt (sigmoid)
calib_platt = CalibratedClassifierCV(base_estimator=clf, method='sigmoid', cv='prefit')
calib_platt.fit(X_calib, y_calib)
probs_platt = calib_platt.predict_proba(X_test)[:, 1]
print('Brier (Platt):', brier_score_loss(y_test, probs_platt))
# Isotonic
calib_iso = CalibratedClassifierCV(base_estimator=clf, method='isotonic', cv='prefit')
calib_iso.fit(X_calib, y_calib)
probs_iso = calib_iso.predict_proba(X_test)[:, 1]
print('Brier (Isotonic):', brier_score_loss(y_test, probs_iso))
En un ejemplo hipotético, puede observar: No calibrado 0.09 → Platt 0.07 → Isotonic 0.05, cuando hay datos suficientes. Si Isotonic presenta peor rendimiento, es probable que haya overfitted en la calibración.
Paso 5: Evaluar la calibración (curva de calibración y Brier)
Use el Brier score para una medida agregada y la curva de calibración para inspeccionar dónde ocurren desviaciones. La curva agrupa probabilidades en bins (p. ej.: 10) y compara la probabilidad media predicha con la fracción positiva observada. Si la curva está por debajo de la diagonal, el modelo tiende a ser optimista; por encima, pesimista.
from sklearn.calibration import calibration_curve
import matplotlib.pyplot as plt
def plot_calibration(y_true, probs_list, labels):
plt.figure(figsize=(6,6))
for probs, label in zip(probs_list, labels):
frac_pos, mean_pred = calibration_curve(y_true, probs, n_bins=10)
plt.plot(mean_pred, frac_pos, marker='o', label=label)
plt.plot([0,1],[0,1],'k:', label='Perfecta')
plt.xlabel('Probabilidad media prevista')
plt.ylabel('Fracción positiva observada')
plt.legend()
plt.grid(True)
plt.show()
plot_calibration(y_test, [probs_uncal, probs_platt, probs_iso], ['No calibrado','Platt','Isotonic'])
Interprete los puntos: si Platt sigue la diagonal más de cerca que el modelo no calibrado, se ha ganado robustez. Si Isotonic muestra fluctuaciones grandes entre bins, puede ser señal de poca muestra por bin.
Paso 6: Elegir método y evitar overfitting
Reglas prácticas: use Platt cuando tiene pocas decenas a algunas centenas de ejemplos para calibración; use Isotonic cuando tiene varias centenas o miles y sospecha de una relación no lineal. Siempre prefiera validación cruzada estratificada (cv=5) cuando no hay un conjunto de calibración independiente. Para clases raras, aumente el tamaño del conjunto de calibración o use técnicas de remuestreo con cuidado.
Verificar el resultado
Confirme que el Brier score ha disminuido y que la curva de calibración se aproxima a la línea diagonal para el método elegido. Pruebe también el impacto en métricas de negocio: por ejemplo, si aplica un umbral de 0.7 para actuar, verifique cambios en las tasas de falsos positivos/negativos. Si Isotonic empeora en la prueba, es señal de overfitting en la calibración — vuelva a usar Platt o aumente el conjunto de calibración.
Conclusión
Calibrar probabilidades en Machine Learning con CalibratedClassifierCV (Platt o Isotonic) es una forma sencilla de hacer las predicciones más fiables, especialmente en aplicaciones sensibles a probabilidades (por ejemplo, scoring de riesgo, cribado clínico). Próximos pasos: experimentar validación cruzada para calibración, probar otros clasificadores, usar estratificación y medir impacto en los umbrales de decisión. Consejo práctico: reserve siempre un conjunto independiente para calibración cuando sea posible y documente las diferencias de Brier y curva de calibración antes/después.