A nota anterior, “Um threshold é uma decisão”, leu o threshold operacional do modelo Credit Default como uma razão de custos — \(\tau = 0{,}24\) significa que deixar passar um inadimplente custa cerca de \(3{,}2\times\) um falso alarme — e terminou com uma ressalva: essa leitura só vale se os escores forem probabilidades calibradas. Esta nota faz a verificação.
§1O que é “calibrado”
Um escore \(\hat p\) é calibrado quando, entre todos os clientes que recebem o escore \(p\), uma fração \(p\) de fato fica inadimplente:
A qualidade de ordenação (ROC AUC) não diz nada sobre isso: qualquer transformação crescente de \(\hat p\) tem a mesma AUC. Três medidas, todas calculadas no conjunto de teste intocado:
além da log loss. O ECE (erro de calibração esperado) compara, em cada um de 10 bins de probabilidade, a probabilidade prevista média \(\bar p_b\) com a taxa de inadimplência observada \(\bar y_b\).
§2Protocolo
- O mesmo split do projeto. Treino/teste 80/20 estratificado e depois treino/validação 80/20, ambos com
random_state = 42. - Modelo salvo. O pipeline de produção foi re-treinado nas 24.000 linhas de treino, então é avaliado apenas nas 6.000 de teste.
- Recalibrar exige dados que o modelo nunca viu. Os mesmos hiperparâmetros foram re-treinados nas 19.200 linhas; Platt scaling (regressão logística sobre o logit) e regressão isotônica foram ajustados nas 4.800 de validação; tudo foi avaliado no teste.
- Checagem. O refit reproduz o notebook exatamente: \(\tau = 0{,}24\), F1 = 0,5405 e ROC AUC = 0,7833 na validação. O modelo salvo dá ROC AUC = 0,7770 no teste, como reportado.
§3Resultado: os escores já são calibrados
Os pontos ficam sobre a diagonal. No conjunto de teste inteiro, a probabilidade prevista média é 0,2213, contra uma taxa real de inadimplência de 0,2212, e o ECE = 0,0076 (intervalo bootstrap de 95%: 0,007–0,020; o ECE é viesado para cima em amostras finitas, por isso o intervalo pende para a direita). As maiores diferenças são uma leve superconfiança nos bins de 0,6 a 0,8 (previsto 0,66 contra observado 0,62, e 0,75 contra 0,72) — com cerca de 240 clientes por bin, isso dá cerca de 1 a 1,2 erro-padrão, dentro do ruído.
| modelo | Brier | log loss | ECE | ROC AUC | p̂ médio | g(0,24) | cFN/cFP |
|---|---|---|---|---|---|---|---|
| salvo (24k) | 0,1355 | 0,4310 | 0,0076 | 0,7770 | 0,2213 | 0,240 | 3,17× |
| refit, bruto | 0,1352 | 0,4301 | 0,0124 | 0,7794 | 0,2208 | 0,240 | 3,17× |
| refit + Platt | 0,1352 | 0,4300 | 0,0098 | 0,7794 | 0,2232 | 0,244 | 3,11× |
| refit + isotônica | 0,1356 | 0,4394 | 0,0102 | 0,7781 | 0,2238 | 0,272 | 2,68× |
Conjunto de teste (n = 6.000, taxa real de inadimplência = 0,2212). Calibradores ajustados na validação (n = 4.800). g(0,24) = probabilidade calibrada correspondente ao threshold bruto 0,24.
A recalibração confirma pelo outro lado. O mapa de Platt ajustado é \(\operatorname{logit} g(p) = 0{,}978\,\operatorname{logit} p - 0{,}006\) — quase a identidade. A regressão isotônica chega a piorar a log loss (0,4394 contra 0,4301): com 4.800 linhas de validação, sua função em degraus ajusta ruído.
§4Então τ = 0,24 é uma razão de custos?
Sim, aproximadamente. A recalibração é monótona, então não muda nenhuma decisão — muda apenas o que o threshold significa. Passando o corte bruto por cada calibrador, obtém-se
A leitura de negócio se sustenta: o modelo trata deixar passar um inadimplente como cerca de três vezes mais caro que um falso alarme. Agora isso é uma afirmação defensável, não uma premissa.
§5Uma correção: o próprio threshold é ruidoso
A nota anterior comparou o ótimo empírico 0,24 com o threshold teórico que maximiza o F1 para escores calibrados, \(F1^{*}/2 \approx 0{,}27\), e atribuiu a diferença a uma calibração imperfeita. A calibração está boa, então essa explicação estava errada. Reamostrando a validação 500 vezes e recalculando o threshold ótimo para F1, obtém-se um intervalo bootstrap de 95% de [0,22; 0,33] (mediana 0,24). A curva de F1 na validação é plana — entre 0,532 e 0,541 para todo \(\tau\) de 0,22 a 0,30 —, então 0,27 está bem dentro do ruído. A diferença é variabilidade amostral, não descalibração.
§6Conclusões
- Verifique a calibração antes de ler escores como probabilidades — e antes de “corrigi-la”. Aqui, recalibrar acrescentaria um componente sem melhorar nada.
- Recalibrar tem custo: a regressão isotônica sobreajusta conjuntos de calibração pequenos. Platt scaling é o padrão mais seguro quando há poucos dados.
- Um threshold ótimo é uma estimativa. Reporte sua incerteza; numa função objetivo plana, 0,24 contra 0,27 não significa nada.
- Com a calibração verificada, a probabilidade devolvida pela API pode ser lida literalmente: um cliente com escore 0,30 pertence a um grupo em que cerca de 30% ficam inadimplentes.
Código e resultados: research/calibration/ (scikit-learn 1.9.0, xgboost 3.3.0) · Modelo: github.com/Igor-Millis/credit-default-api · Platt, J. (1999), Probabilistic outputs for support vector machines; Niculescu-Mizil & Caruana (2005), Predicting good probabilities with supervised learning, ICML.