Como criar um calibrador de probabilidade em Machine Learning
Calibrar probabilidades em Machine Learning melhora a confiança nas previsões de modelos de classificação (por exemplo, quando um modelo diz 0.9, isso deve corresponder a 90% de ocorrência). Este tutorial mostra como criar um calibrador de probabilidade em Python usando scikit-learn, explicando por que e como evitar erros comuns.
Pré-requisitos
- Python 3.8+ com scikit-learn instalado
- Noções básicas de classificação binária (probabilidades, métricas como ROC/AUC)
- IDE ou Jupyter Notebook para executar código
Passo 1: Perceber porquê calibrar probabilidades
Modelos como RandomForest ou SVM nem sempre devolvem probabilidades bem calibradas. A saída de predict_proba reflecte a confiança do modelo segundo a sua própria estrutura, não necessariamente a frequência real observada. Calibrar ajusta as probabilidades previstas para que a frequência observada se aproxime das probabilidades preditas: por exemplo, entre as instâncias onde o modelo prevê ~0.8, cerca de 80% deveriam ser positivas.
Erros comuns: calibrar sobre os mesmos dados de treino (causa overfitting), usar Isotonic com poucos exemplos (overfitting não paramétrico) ou esquecer de manter a mesma distribuição de classes entre treino, calibração e teste. Em problemas com 10% de positivos, a calibração deve preservar essa estratificação — idealmente usando stratify nas divisões ou validação cruzada estratificada.
Passo 2: Preparar dados de exemplo
Use um dataset simples para praticar. O conjunto breast_cancer do scikit-learn tem 569 amostras: se seguir a divisão abaixo (60% treino, 20% calibração, 20% teste), terá aproximadamente 341 amostras para treino e 114 para calibração e teste cada. Ter algumas centenas de exemplos na fase de calibração é ú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)
Passo 3: Treinar um modelo base sem calibrar
Treine um classificador padrão e obtenha previsões não calibradas para servir de linha de base. Aqui usamos RandomForestClassifier por ser comum em problemas tabulares. Meça o Brier score como métrica da qualidade probabilística — quanto mais próximo de 0, melhor.
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 (não calibrado):', brier_score_loss(y_test, probs_uncal))
Como referência, num caso típico com este dataset pode ver Brier ~0.06-0.12 dependendo da semente; o objectivo é reduzir esse valor com calibração.
Passo 4: Calibrar com CalibratedClassifierCV (Platt e Isotonic)
scikit-learn oferece CalibratedClassifierCV que implementa Platt scaling (método 'sigmoid') e Isotonic. Platt ajusta uma regressão logística aos scores do classificador e é paramétrico — menos susceptível a overfitting quando a amostra de calibração é pequena. Isotonic é não paramétrico (função monotónica livre) e pode capturar relações mais complexas se houver muitas amostras de calibração.
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))
Num exemplo hipotético, pode observar: Não calibrado 0.09 → Platt 0.07 → Isotonic 0.05, quando há dados suficientes. Se Isotonic apresentar pior desempenho, é provável que tenha overfitted na calibração.
Passo 5: Avaliar calibração (curva de calibração e Brier)
Use o Brier score para uma medida agregada e a curva de calibração para inspecionar onde ocorrem desvios. A curva agrupa probabilidades em bins (ex.: 10) e compara a probabilidade média prevista com a fracção positiva observada. Se a curva está abaixo da diagonal, o modelo tende a ser optimista; acima, pessimista.
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='Perfeita')
plt.xlabel('Probabilidade média prevista')
plt.ylabel('Fração positiva observada')
plt.legend()
plt.grid(True)
plt.show()
plot_calibration(y_test, [probs_uncal, probs_platt, probs_iso], ['Não calibrado','Platt','Isotonic'])
Interprete os pontos: se Platt segue a diagonal mais de perto do que o modelo não calibrado, ganhou-se robustez. Se Isotonic mostra flutuações grandes entre bins, pode ser sinal de pouca amostra por bin.
Passo 6: Escolher método e evitar overfitting
Regras práticas: use Platt quando tem poucas dezenas a algumas centenas de exemplos para calibração; use Isotonic quando tem várias centenas ou milhares e suspeita de uma relação não linear. Sempre prefira validação cruzada estratificada (cv=5) quando não há um conjunto de calibração independente. Para classes raras, aumente o tamanho do conjunto de calibração ou use técnicas de reamostragem com cuidado.
Verificar o resultado
Confirme que o Brier score diminuiu e que a curva de calibração aproxima-se da linha diagonal para o método escolhido. Teste também o impacto em métricas de negócio: por exemplo, se aplica um limiar de 0.7 para agir, verifique mudanças nas taxas de falso positivo/negativo. Se Isotonic piorar no teste, é sinal de overfitting na calibração — volte a usar Platt ou aumente o conjunto de calibração.
Conclusão
Calibrar probabilidades em Machine Learning com CalibratedClassifierCV (Platt ou Isotonic) é uma forma simples de tornar previsões mais fiáveis, especialmente em aplicações sensíveis a probabilidades (por exemplo, scoring de risco, triagem clínica). Próximos passos: experimentar validação cruzada para calibração, testar outros classificadores, usar estratificação e medir impacto nos thresholds de decisão. Dica prática: reserve sempre um conjunto independente para calibração quando possível e documente as diferenças de Brier e curva de calibração antes/depois.