Machine learning desde cero · Lección 2.4 · 11 de 33 lecciones listas · 12 min
Calibración: ¿0,8 significa 80 %?
En pocas palabras
Un modelo puede ordenar bien y dar mal los porcentajes. Naive Bayes declara un 98 % y acierta el 88 %. La temperatura lo arregla sin cambiar ninguna decisión.
Calentamiento Dos preguntas de lecciones anteriores. Un minuto, y no bloquea la lección.
En la lección 2.3 las curvas ROC y PR comprobaban lo bien que un modelo ordena las biopsias. No preguntaban si los números del modelo son ciertos. El modelo dice «0,8». ¿Significa que el 80 % de esas biopsias son malignas? Esa es la pregunta de la calibración. Hoy la comprobarás con dos modelos y verás que a veces un solo número la arregla, sin cambiar ninguna decisión.
Elige una respuesta y tu grado de seguridad.
Responde para desbloquear el experimento.
Experimento interactivo
Este experimento interactivo funciona en un navegador con JavaScript activado. El texto que lo rodea describe lo que muestra.
Ver la respuesta
Respuesta correcta: En un 88 %, es decir, 10 puntos menos de lo que promete
Declara de media un 98,3 % y acierta el 88,3 %: una diferencia de 10,0 puntos. 149 de las 171 biopsias reciben una confianza superior al 99 %, y 5 de ellas son errores. La temperatura T = 4,12 baja el Brier de 0,100 a 0,071 y no cambia ni una decisión.
Prueba
- Empieza con naive Bayes sin calibrar. ¿Dónde están los círculos respecto a la diagonal? ¿Cuántas biopsias reciben una confianza superior al 99 % y cuántas de ellas son errores?
- Activa la temperatura. ¿Qué pasa con los círculos, con el Brier y con el ROC AUC? ¿Cuántas decisiones han cambiado?
- Cambia a la regresión logística y compárala sin calibrar y con temperatura. ¿Necesitaba arreglo este modelo?
Cuando lo hayas comprobado en el lab, pongamos nombre a lo que ves.
La idea en palabras sencillas
Un modelo está calibrado cuando sus números se pueden tomar al pie de la letra: entre las biopsias a las que da 0,8, alrededor del 80 % son malignas, y entre las de 0,1, alrededor del 10 %. Lo comprueba el diagrama de fiabilidad. Las biopsias se reparten en franjas según la probabilidad declarada y en cada franja se cuenta qué parte es realmente maligna. Un modelo calibrado está sobre la diagonal. Los círculos por debajo de la diagonal a la derecha indican exceso de confianza.
Calibrar no es lo mismo que ordenar. El ROC AUC de la lección 2.3 solo pregunta si una biopsia maligna recibe una puntuación más alta que una benigna. Naive Bayes ordena bien (ROC AUC 0,966, casi como la regresión logística con 0,969), pero sus porcentajes están inflados. Entre las 55 biopsias a las que da al menos 0,9, declara de media un 99,6 %, y son malignas el 89,1 %.
El Brier score mide las dos cosas a la vez: la media del cuadrado de la diferencia entre la probabilidad declarada y lo que pasó (1 para maligna, 0 para benigna). Cuanto menos, mejor. El ECE dice a qué distancia media de la diagonal quedan los círculos.
Jak to policzono
- Biopsias: Breast Cancer Wisconsin (Diagnostic), UCI, licencia CC BY 4.0. 569 biopsias, 10 medidas «mean» de cada una.
- División estratificada: 171 biopsias de validación (30 %); del resto, 266 para aprender y 132 para ajustar la calibración. Ni el modelo ni la calibración ven las biopsias de validación.
- Modelos: naive Bayes con distribución normal (
GaussianNB) y estandarización más regresión logística (C = 1). - Temperatura: un solo número T, ajustado con las 132 biopsias de calibración para que el log-loss sea mínimo. Diagrama y ECE: 10 franjas de 0,1.
Por qué funciona
Naive Bayes supone que las medidas de un tumor son independientes entre sí. En estos datos no lo son: el radio, el perímetro y el área del tumor dicen casi lo mismo. Así que el modelo cuenta varias veces la misma prueba y la va sumando a la puntuación hasta que su confianza llega al 99 % y más. El orden de las biopsias sigue teniendo sentido, porque un tumor más grande sigue recibiendo una puntuación más alta, pero los porcentajes crecen demasiado rápido.
La temperatura divide la puntuación del modelo antes de la sigmoide entre un solo número T. Para naive Bayes T = 4,12, así que cada puntuación se reduce más de cuatro veces. Dividir entre un número positivo no cambia ni el signo de la puntuación ni el orden de las biopsias. Ninguna decisión con el umbral 0,5 cambia, y el ROC AUC sigue en 0,966. Solo cambian los porcentajes: la confianza media baja del 98,3 % al 91,1 %, el Brier de 0,100 a 0,071 y el ECE de 0,101 a 0,055. Ahora 34 biopsias reciben una confianza superior al 99 %, y ninguna es un error.
La regresión logística está calibrada casi desde el principio: declara un 92,5 % y acierta el 91,2 %. Su temperatura sale T = 0,93, cerca de 1, y el Brier se queda en 0,063. No es casualidad: la regresión logística aprende reduciendo el log-loss, que es justo la penalización por dar mal los porcentajes.
No es la casualidad de una sola división. En el código de abajo el mismo experimento se repite con otras 50 divisiones: naive Bayes declara de media un 98,5 % y acierta el 91,2 %, y la temperatura baja su Brier todas las veces. A la regresión logística la temperatura casi no le cambia nada.
Error frecuente
¿Verdadero o falso?: «una puntuación de 0,8 significa un 80 % de probabilidad». Falso, mientras no lo compruebes. Un modelo da un número de 0 a 1, pero nada garantiza que sea una probabilidad en el sentido de siempre. En el lab naive Bayes da a 149 de las 171 biopsias una confianza superior al 99 %, y 5 de ellas son errores. Si esos porcentajes fueran ciertos, entre ellas habría menos de dos errores. Lee la puntuación de un modelo como probabilidad solo después de comprobar el diagrama de fiabilidad con datos que el modelo no ha visto.
Un aviso en sentido contrario: calibrar no mejora el orden. La temperatura no cambia ni el ROC AUC ni la exactitud, y a un modelo bien calibrado no le aporta nada: el Brier de la regresión logística se queda en 0,063. La calibración hace falta cuando los números del modelo van más allá: a un umbral según el coste de los errores (lección 2.6), a sumar riesgos, a una conversación con un paciente.
Test
Tres preguntas para comprobar lo aprendido. Elige una respuesta o despliega la solución bajo cada pregunta. Con el teclado: las flechas eligen, Enter o Espacio confirma.
Ideas clave
- La calibración pregunta si los porcentajes del modelo son ciertos; ordenar (ROC AUC) es otra pregunta.
- La calibración se comprueba con un diagrama de fiabilidad y el Brier score en datos que el modelo no ha visto.
- Naive Bayes se confía demasiado porque cuenta varias veces la misma prueba de medidas relacionadas.
- La temperatura arregla los porcentajes con un solo número y no cambia ninguna decisión ni el ROC AUC.
Más a fondo: fórmula, código, práctica
Las matemáticas
Diagrama de fiabilidad: en una franja B de probabilidades declaradas comparas la media declarada conf(B) con la proporción de positivos acc(B). Un modelo calibrado cumple P(y = 1 | p) = p.
Brier = (1/n) · Σ (pᵢ − yᵢ)², y ECE = Σ_B (|B| / n) · |acc(B) − conf(B)|.
Temperatura: el modelo da una puntuación z (logit) y la probabilidad es p = σ(z / T), donde σ(z) = 1 / (1 + e^(−z)). T se ajusta en una parte aparte de los datos, reduciendo el log-loss. Cuando T > 1, los porcentajes se aplanan. El signo de z / T es el de z, así que la decisión p ≥ 0,5 (es decir, z ≥ 0) no cambia.
Platt: p = σ(a · z + b), dos números en lugar de uno. El desplazamiento b puede cambiar decisiones: en el lab cambia 2 para naive Bayes.
En código (Python)
El mismo experimento en scikit-learn con 50 divisiones aleatorias (266 biopsias para aprender, 132 para calibrar, 171 para evaluar): confianza media, exactitud y Brier antes y después de la temperatura.
import numpy as np
from scipy.optimize import minimize_scalar
from scipy.special import expit
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.naive_bayes import GaussianNB
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import brier_score_loss
X, y = load_breast_cancer(return_X_y=True)
X, y = X[:, :10], 1 - y # las 10 medidas "mean", como en el lab; 1 = maligno
def score(m, rows): # puntuación del modelo antes de la sigmoide: log P(maligno) - log P(benigno)
lp = m.predict_log_proba(X[rows])
return lp[:, 1] - lp[:, 0]
def run(model, seed): # 266 para aprender, 132 para calibrar, 171 para evaluar (validación)
rest, va = train_test_split(np.arange(len(y)), test_size=0.3, stratify=y, random_state=seed)
tr, ca = train_test_split(rest, test_size=1 / 3, stratify=y[rest], random_state=seed)
m = model.fit(X[tr], y[tr])
zc, zv = score(m, ca), score(m, va)
loss = lambda T: np.mean(np.logaddexp(0, -zc / T) * y[ca] + np.logaddexp(0, zc / T) * (1 - y[ca]))
T = minimize_scalar(loss, bounds=(0.05, 20), method="bounded").x # temperatura: un solo número, ajustado en la parte de calibración
p0, p1 = expit(zv), expit(zv / T)
conf, acc = np.maximum(p0, 1 - p0).mean(), ((p0 >= 0.5) == y[va]).mean()
same = ((p0 >= 0.5) == (p1 >= 0.5)).all() # dividir entre T nunca cambia una decisión
return conf, acc, brier_score_loss(y[va], p0), brier_score_loss(y[va], p1), T, same
for name, model in (("naive Bayes", GaussianNB()), ("logistic regression", make_pipeline(StandardScaler(), LogisticRegression()))):
r = np.array([run(model, s) for s in range(50)])
print(f"{name}, 50 splits: declares {r[:, 0].mean():.1%}, accuracy {r[:, 1].mean():.1%}; Brier {r[:, 2].mean():.3f} -> {r[:, 3].mean():.3f} with T = {r[:, 4].mean():.2f}; lower in {(r[:, 3] < r[:, 2]).sum()} of 50, decisions kept in {int(r[:, 5].sum())} of 50")
Resultado
naive Bayes, 50 splits: declares 98.5%, accuracy 91.2%; Brier 0.077 -> 0.061 with T = 3.86; lower in 50 of 50, decisions kept in 50 of 50
logistic regression, 50 splits: declares 93.4%, accuracy 93.5%; Brier 0.047 -> 0.047 with T = 0.94; lower in 17 of 50, decisions kept in 50 of 50
Las divisiones son distintas de las del lab, así que los números también: naive Bayes declara de media un 98,5 % y acierta el 91,2 %. La imagen es la misma. La temperatura baja su Brier en 50 divisiones de 50 y no cambia ninguna decisión, mientras que a la regresión logística casi no le hace nada: Brier 0,047 antes y después.
Descargar el notebook (.ipynb). Ábrelo en Jupyter o súbelo a Google Colab; descarga por sí solo los datos que falten.
Para profesionales
- En scikit-learn la calibración se comprueba con
calibration_curve,CalibrationDisplayybrier_score_loss, siempre con datos que el modelo no ha visto. - La arregla
CalibratedClassifierCV(method="sigmoid"es Platt,"isotonic"es la regresión isotónica); la temperatura es fácil de añadir a mano. La regresión isotónica necesita más datos, porque ajusta toda una función escalonada. - Ajusta la calibración en una parte aparte de los datos o dentro de la validación cruzada, nunca con los datos de los que aprendió el modelo: ahí el modelo parece mejor de lo que es.
- Los porcentajes calibrados importan cuando el número va más allá: a un umbral según el coste de los errores (lección 2.6), a sumar riesgos, a una conversación con un paciente. Cuando solo importa el orden, basta con el ROC AUC.
¿Te ha sido útil?
¡Gracias! Nos ayuda a mejorar.
Profundiza en el Atlas
Entradas de la enciclopedia sobre las ideas de esta lección: