Calibracion de Modelos de Inteligencia Artificial.

Debería ser considerado por todo desarrollador como un paso fundamental en el proceso de aprendizaje automático. La finalidad de la calibración es "ajustar" las probabilidades que el modelo predice para que la realidad sea mejor reflejada por el modelo.

Las CNNs o Convolutional Neural Networks, en general tiene salidas que no estan bien calibradas, por lo que los valores de probabilidad que arrojan no se alinean con la verdadera realidad.

Por ejemplo una red le da el 90% de probabilidades a una clase de ser el resultado de la prediccion. Sin la calibracion, corremos el riesgo de que la realidad sobre la tasa de exito sobre esa clase es menor o mucho menor.

Que importancia tiene?

Obtener la clase mas probable de una prediccion NO es suficiente, ademas necesitamos entender que tan seguro esta el modelo sobre esa prediccion. Si el modelo no esta bien calibrado seguro va a sobreestimar la confianza en las predicciones incorrectas.

Ademas un modelo que esta bien calibrado va a proporcionarnos mucho mejores probabilidades. Las cuales pueden ser aprovechadas mejor a la hora de tomar decisiones, evitando falsas alarmas.

Finalmente si el modelo se utiliza en un area donde la toma de decisiones debe ser totalmente transparente, calibrar nos ayuda a entender que las predicciones son justas y justificadas.

Que metodos existen para calibrar?

Dentro de los mas desarrollados tenemos a Platt Scaling, Isotonic Regression y Temperature Scaling.

Platt Scaling, es una tecnica muy utilizada, que toma como base una regresion logistica a la salida de un modelo, es decir en el vector de salida de la capa totalmente conectada. Esta capa ofrece valores de evidencia o logits, que el modelo acumulo para cada clase. Estos valores todavia NO son probabilidades y no estan en el rango de 0 a 1. Para eso, habria que pasarlos por una funcion de activacion como la funcion sigmoide si la salida es binaria o la funcion softmax si la salida es multiple.

Porque se usan los logits? Basicamente porque son los valores sin "normalizar" y permiten que el modelo trabaje sin restricciones, es decir los valores no estan acotados entre 0 y 1. Facilitando que la red pueda aprender sin las limitaciones de las probabilidades. De esta forma ajusta las predicciones a probabilidades mejor calibradas.

Isotonic Regression, es una tecnica que ajusta las probabilidades, mientras mantiene el orden de las predicciones en otras palabras, si una clase tiene mayor probabilidad antes de la calibracion, seguira siendo mayor despues de la calibracion.

Temperature Scaling, es la version simplificada de Platt Scaling y lo que hace es ajustar las salidas del modelo, mientras las divide por una constante llamada temperatura. Esta constante se ajusta con el fin de darle una mejor distribucion de probabilidad.

Veamos algunos ejemplos.

En el caso de que deseemos utilizar Platt Scaling, tenemos que tener en cuenta que es mas eficiente para salidas binarias es decir cuando solo tenemos 2 posibilidades para clasificar. Sin embargo puede ser utilizado en multiples clases sin problema.

Imaginemos que obtuvimos todas las predicciones sin calibrar de una red CNN, sobre un conjunto de datos para la calibracion. Intentemos poner esto en codigo python y entrenar un modelo en Platt Scaling:

from sklearn.linear_model import LogisticRegression

# Asi logramos las probabilidades sin calibrar del modelo
prob_no_calibradas = model.predict_proba(X_calibration)

# Ajustemos la regresion logistica
platt_model = LogisticRegression(), platt_model.fit(prob_no_calibradas, y_calibration)

Ahora con el modelo ya entrenado, vamos a calibrar las nuevas predicciones.

# Generemos nuevas predicciones del modelo
prob_no_calibradas_nuevas = model.predict_proba(X_new)

# Apliquemos la calibracion de Platt Scaling
prob_calibradas = platt_model.predict_proba(prob_no_calibradas_nuevas)
print(f"Estas son las Probabilidades calibradas: {prob.calibradas}")

Ahora y para finalizar evaluemos la calibracion, mediante la expectativa de error en la calibracion.

Para esto usamos el Error de Calibracion Esperado (ECE), este error es una metrica que mide la diferencia entre la probabilidad predicha y la frecuencia real de ocurrencia de la clase predicha.

import numpy as np
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.calibration import calibration_curve

# Función que calcula el error de calibración esperado (ECE)
def expected_calibration_error(probabilities, true_labels, n_bins=10):
    """
    Calcula el error de calibración esperado (ECE).
    probabilities: Probabilidades predichas por el modelo.
    true_labels: Etiquetas verdaderas (0 o 1).
    n_bins: Número de intervalos (bins) para agrupar las probabilidades.
    """
    bin_boundaries = np.linspace(0, 1, n_bins + 1)
    bin_indices = np.digitize(probabilities, bin_boundaries, right=True) - 1
    ece = 0.0

    for i in range(n_bins):
        # Selecciona los índices correspondientes al bin actual
        in_bin = (bin_indices == i)
        prop_in_bin = np.mean(in_bin)
        
        if prop_in_bin > 0:
            avg_confidence = np.mean(probabilities[in_bin])
            avg_accuracy = np.mean(true_labels[in_bin])
            ece += np.abs(avg_confidence - avg_accuracy) * prop_in_bin

    return ece

# Creando un conjunto de datos de clasificación binaria simple
X, y = make_classification(n_samples=1000, n_features=10, n_classes=2, random_state=42)

# Dividiendo el conjunto en datos de entrenamiento y prueba
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# Entrenando el modelo de regresión logística
model = LogisticRegression()
model.fit(X_train, y_train)

# Prediciendo las probabilidades del conjunto de prueba
probabilities = model.predict_proba(X_test)[:, 1]

# Calculando el ECE
ece = expected_calibration_error(probabilities, y_test, n_bins=10)
print(f'Error de Calibración Esperado (ECE): {ece:.4f}')

Con el codigo de arriba logramos determinar que el error ECE es de:

El error es bajo pero esta presente.

Con todo lo hasta aca visto debe quedarnos mas claro porque la calibracion es crucial para mejorar la confianza en las predicciones de los modelos de clasificacion. Y por cierto, tanto Platt Scaling y Temperature Scaling se pueden aplicar de forma directa despues de entrenar la red.

Bueno es hora de que pongas en practica este nuevo conocimiento.

Y como te digo siempre, no dudes en mandarme un mail si necesitas ayuda.