← Redes Neurais Artificiais e Deep Learning · Insper/8. Métricas e AvaliaçãoMaterial complementar

Material de referência · Laboratório de 2 horas

O modelo que não faz nada
acerta 97,5%.

Vinte mil transações, das quais 2,5% são fraude. Nesta aula nenhum modelo é ajustado depois do bloco 2: o que muda, do começo ao fim, é qual número olhamos — e cada troca muda a decisão que o sistema toma. O limiar padrão de 0,5 custa o dobro do limiar escolhido por custo. A AUC-ROC diz que dois modelos são quase iguais enquanto a precisão média diz que um é duas vezes o outro. E a probabilidade que o modelo declara está errada até alguém medir.

20 000Transações
2,5%Taxa base
3Modelos comparados
7Figuras de execuções reais
6Checkpoints

Abertura · 8 min

A métrica não é o relatório. É a especificação.

Escolher uma métrica é escolher que erro você prefere cometer. Essa escolha acontece com ou sem você — o valor padrão também é uma escolha, só que feita por outra pessoa.

As páginas da aula tratam as métricas uma a uma. Este roteiro faz o contrário: pega um único problema e o percorre inteiro, do dado cru até a decisão, mostrando em cada passo qual número foi olhado e o que ele custou. As quatro perguntas, na ordem em que aparecem num projeto de verdade:

A perguntaO número que respondeO que dá errado quando você pula
O modelo aprendeu alguma coisa?Comparação com a linha de base trivialVocê comemora 97,5% de acurácia que o return 0 também tira.
Qual dos modelos é melhor?Precisão média (AP), não AUC-ROCVocê escolhe o modelo errado — e neste handout as duas métricas discordam.
Onde cortar?O custo dos dois errosFica no 0,5 de fábrica e paga o dobro.
Posso confiar na probabilidade?ECE e a curva de confiabilidadeToda conta de valor esperado feita em cima dela sai errada.
Nenhuma dessas perguntas é respondida por "acurácia".
Ao final desta aula o aluno consegue
  • Dizer, diante de qualquer número de acurácia, o que a linha de base trivial marca — e recusar o número se ninguém disser.
  • Escolher entre ROC e precisão-recall a partir da taxa base, e explicar por que a primeira quase não se mexe quando a segunda desaba.
  • Derivar o limiar ótimo a partir do custo dos dois erros, e medir o quanto o padrão 0,5 custou.
  • Medir calibração (ECE, curva de confiabilidade), corrigi-la com escala de Platt e mostrar que nenhuma métrica de ordenação se mexeu.
  • Fazer o mesmo em regressão: reportar contra a linha de base, ler RMSE/MAE, e olhar o gráfico de resíduos antes de acreditar em qualquer resumo.
Como esta aula funciona
  • Em duplas, um notebook aberto. Seis checkpoints; escreva a resposta antes de abrir a solução.
  • Todos os números vêm de execuções reais, com semente fixa, do código do apêndice B. Rodar de novo dá exatamente os mesmos valores.
  • Os dados de fraude são sintéticos, e de propósito. A aula precisa controlar a taxa base — é ela que produz todos os fenômenos daqui — e nenhuma base pública dá esse controle. O modelo, as métricas e os limiares são medidos de verdade. O bloco 6 usa dados reais.

Bloco 1 · 12 min

A taxa base, e a armadilha que ela arma

Antes de qualquer métrica: quantos positivos existem? Esse número sozinho já determina quais métricas vão mentir para você.

image/svg+xml Matplotlib v3.10.9, https://matplotlib.org/
À esquerda, em escala logarítmica, porque em escala linear a barra da fraude some. À direita, as probabilidades que o modelo atribui a cada classe no conjunto de teste: elas se sobrepõem, e é dessa sobreposição que nasce a necessidade de escolher um limiar. Se não houvesse sobreposição não haveria decisão a tomar.
from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split

X, y = make_classification(
    n_samples=20000, n_features=12, n_informative=5, n_redundant=2,
    weights=[0.98, 0.02], flip_y=0.01, class_sep=1.1, random_state=7)

X_tr, X_tmp, y_tr, y_tmp = train_test_split(X, y, test_size=0.4, random_state=0, stratify=y)
X_val, X_te, y_val, y_te = train_test_split(X_tmp, y_tmp, test_size=0.5, random_state=0, stratify=y_tmp)

print(y.mean(), y_te.sum(), len(y_te))
# 0.0248   99   4000

Repare no stratify=y: sem ele, uma partição aleatória de um conjunto com 2,5% de positivos produz partições com taxas base diferentes entre si, e aí todas as comparações do resto da aula ficam contaminadas por essa diferença.

O número que qualquer relatório de acurácia precisa trazer ao lado

No conjunto de teste, return 0 — prever "legítima" sempre — acerta 97,52%. Qualquer modelo que apareça com 97% de acurácia neste problema está, até prova em contrário, empatado com uma função que não olha os dados. É por isso que a primeira pergunta diante de uma acurácia é sempre quanto tira o classificador trivial?

Checkpoint 1 · quantas fraudes existem, de verdade?

O conjunto de teste tem 4 000 transações e 99 fraudes. Se um modelo tem recall de 30%, quantas fraudes ele deixa passar? E se você quiser reduzir esse número pela metade, qual das duas colunas da matriz de confusão vai crescer — e por quê é impossível não crescer?

resposta

Deixa passar 69 (99 × 0,70). Para pegar metade das que escapam você precisa baixar o limiar, e baixar o limiar aumenta todos os alertas — os certos e os errados. Cresce a coluna dos falsos positivos. Não há como evitar: as duas distribuições da figura 1 se sobrepõem, então qualquer corte que capture mais fraudes captura também mais legítimas daquela faixa. A pergunta útil não é "como evito isso", é quantos falsos positivos vale a pena pagar por uma fraude a menos — que é exatamente a conta do bloco 4.

Bloco 2 · 15 min

O limiar que ninguém escolheu

O predict() de qualquer biblioteca corta em 0,5. Esse valor não veio do seu problema — veio do valor padrão de uma função.

O modelo desta aula é uma floresta aleatória, treinada uma vez e nunca mais tocada. O que muda daqui em diante é só onde cortamos a probabilidade que ela devolve:

image/svg+xml Matplotlib v3.10.9, https://matplotlib.org/
A mesma floresta, o mesmo conjunto de teste, três limiares. Em 0,5 ela quase não erra um alerta (precisão 83%) e deixa passar 69 das 99 fraudes. Em 0,03 pega 78 das 99 e dispara 526 alertas falsos. Nenhum dos três está "certo" — cada um é uma política diferente sobre qual erro doer menos.
LimiarAcuráciaPrecisãoRecallF1Fraudes perdidasAlertas falsos
0,50 (o padrão)98,1%83,3%30,3%0,444696
0,1597,6%50,4%60,6%0,5503959
0,0386,3%12,9%78,8%0,22221526
Repare na coluna da acurácia: ela cai de 98,1% para 86,3% enquanto o modelo passa a encontrar duas vezes e meia mais fraude. Num problema desbalanceado, a acurácia melhora quando você desiste de detectar.

Checkpoint 2 · o F1 escolhe bem?

Entre os três limiares, o F1 elege o 0,15. Escreva uma situação em que essa seria a escolha errada, e diga qual dos outros dois você usaria.

resposta

O F1 é a média harmônica de precisão e recall, e média harmônica trata os dois como igualmente importantes. Basta que não sejam.

Quando 0,03 é melhor: a fraude custa caro e o alerta é barato — uma equipe de análise que revisa alertas em segundos, ou uma segunda etapa automática que filtra. Aí perder 21 fraudes em vez de 39 vale muito mais do que 467 alertas falsos a mais.

Quando 0,5 é melhor: o alerta é caro ou tóxico — bloquear o cartão do cliente, acusar alguém, algo que não passa por revisão humana. Nesse regime, 83% de precisão é o que impede o sistema de queimar a confiança do usuário.

O F1 é o valor padrão de quem não quis decidir. O bloco 4 substitui esse chute por uma conta.

Bloco 3 · 20 min

ROC contra precisão-recall

As duas resumem o modelo inteiro, sem escolher limiar. Sob desbalanceamento elas discordam — e uma delas discorda a favor do modelo errado.

Três modelos treinados nos mesmos dados: uma floresta aleatória, uma regressão logística e um naive bayes gaussiano. Primeiro pelas duas curvas:

image/svg+xml Matplotlib v3.10.9, https://matplotlib.org/
À esquerda, a ROC: as três curvas quase se encostam, e o intervalo inteiro das AUCs é de 0,079. À direita, precisão-recall nos mesmos dados: o intervalo das APs é de 0,297 — quase quatro vezes maior. A linha pontilhada é o acaso na segunda curva, e ela vale a taxa base: 2,5%.
ModeloAUC-ROCPrecisão média (AP)Ordem pela AUCOrdem pela AP
Floresta aleatória0,8880,5531º1º
Naive bayes0,8210,2562º3º
Regressão logística0,8090,2763º2º
Não é só uma questão de sensibilidade: as duas métricas ordenam os modelos de forma diferente. Pela AUC-ROC o naive bayes ganha da logística; pela AP, perde. Escolher a métrica é escolher qual modelo vai para produção.

O motivo está em qual erro cada curva mede. A ROC usa a taxa de falsos positivos, e o denominador dela são os 3 901 negativos — mil alertas falsos mexem pouco nessa fração. A precisão usa a contagem de falsos positivos contra a de verdadeiros, e nessa razão mil alertas falsos são a diferença entre um sistema útil e um inútil. Quando a classe positiva é rara, é a segunda conta que descreve a sua vida.

image/svg+xml Matplotlib v3.10.9, https://matplotlib.org/
A mesma floresta, as mesmas pontuações, com os negativos subamostrados para levar a taxa base de 2,5% a 20%. A AUC-ROC sai de 0,888 para 0,898 — praticamente parada, porque as duas taxas que ela usa são internas a cada classe. A AP salta de 0,553 para 0,823, porque o acaso subiu junto: precisão depende de quantos positivos existem.
Como ler uma AP publicada

Uma AP de 0,82 parece muito melhor do que uma de 0,55 e, aqui, é o mesmo modelo. Uma precisão média só significa alguma coisa ao lado da taxa base do conjunto em que foi medida — o piso do acaso. Compare AP com AP no mesmo conjunto; entre conjuntos, compare a razão AP / taxa base, ou não compare.

Checkpoint 3 · qual você reporta?

Você vai apresentar esses três modelos. Qual das duas métricas coloca no slide, e o que responde a quem perguntar "mas a AUC não é o padrão da área?"

resposta

AP, com a taxa base ao lado, e a ROC no apêndice se alguém quiser. O argumento não é que a AUC-ROC seja errada — é que ela responde a outra pergunta: "se eu sortear uma fraude e uma legítima, com que frequência o modelo dá nota maior à fraude?" É uma pergunta simétrica entre as classes, e o nosso problema não é simétrico: ninguém opera um sistema em que fraudes e legítimas aparecem em pares.

A pergunta que a operação faz é "dos alertas que eu vou revisar, quantos são fraude?", e essa é precisão. A tabela acima é o argumento definitivo: as duas métricas discordam sobre qual modelo é o segundo melhor, e só uma delas está respondendo à pergunta que o sistema faz.

Bloco 4 · 20 min

O limiar por custo

Até aqui escolhemos limiares por gosto. Agora por conta — e a diferença é o dobro do dinheiro.

Suponha que revisar um alerta falso custe 5 e deixar passar uma fraude custe 250. Prever "fraude" vale a pena quando o prejuízo esperado de não prever supera o de prever:

p · CFN > (1 − p) · CFP  ⟹  p* = CFP / (CFP + CFN) = 5 / 255 = 0,0196
image/svg+xml Matplotlib v3.10.9, https://matplotlib.org/
À esquerda, precisão, recall e F1 em função do limiar, na validação — nada é uma propriedade do modelo, tudo é uma propriedade do corte. À direita, o custo total, com o zoom na região que decide. O mínimo medido fica em 0,057; a fórmula aponta 0,020; o padrão 0,5 está lá longe, à direita.
Limiar escolhido porValorCusto na validaçãoAcima do mínimo
Mínimo medido na validação0,0577 855—
Fórmula CFP/(CFP+CFN)0,0208 940+14%
Máximo F10,19712 445+58%
O padrão 0,50,50016 305+108%
O valor de fábrica custa o dobro do limiar escolhido. Nenhum modelo foi retreinado entre uma linha e outra — a diferença inteira é a escolha de onde cortar.
Por que a fórmula não caiu no mínimo

A fórmula é exata para probabilidades calibradas: ela diz em que probabilidade verdadeira o valor esperado vira. Se o modelo declara 0,02 onde a frequência real é outra, o corte cai no lugar errado — e é exatamente o que o bloco 5 vai medir. Ainda assim ela chega a 14% do mínimo partindo de nenhum dado, contra 108% do 0,5: use a fórmula para saber onde procurar, e a varredura na validação para escolher.

E cuidado com a precisão que o mínimo medido aparenta: qualquer limiar entre 0,048 e 0,069 fica dentro de 5% do custo mínimo, e o conjunto de validação tem só 99 fraudes. O "0,057" não tem três casas de significado — tem uma faixa.

Checkpoint 4 · a fraude ficou mais barata

A empresa contrata um seguro: o prejuízo de uma fraude não detectada cai de 250 para 50. Sem rodar nada, para que lado anda o limiar ótimo, e por quanto? Depois calcule.

resposta

Sobe, porque o erro que a queda barateou é o de deixar passar — então vale a pena ser mais exigente antes de disparar um alerta. Pela fórmula: p* = 5/(5+50) = 0,091, contra 0,020 de antes: quase cinco vezes maior. Menos alertas, menos revisão, mais fraude passando — e isso agora é a decisão certa, porque a fraude passou a custar cinco vezes menos.

O ponto geral: o limiar não é um hiperparâmetro do modelo, é um parâmetro do negócio. Ele muda quando os custos mudam, sem nenhum retreino. É por isso que vale guardar a probabilidade, e não o rótulo, na saída do seu sistema.

Bloco 5 · 20 min

Calibração: a probabilidade é um número ou um enfeite?

Toda conta do bloco 4 pressupõe que "0,02" quer dizer 2%. Ninguém verificou isso ainda.

A verificação é direta: agrupe as previsões por probabilidade declarada e veja com que frequência elas de fato acontecem. Um modelo calibrado cai sobre a diagonal. O ECE é a distância média até ela, ponderada pelo tamanho de cada faixa.

image/svg+xml Matplotlib v3.10.9, https://matplotlib.org/
À esquerda, o naive bayes: onde ele declara 0,29, a fraude acontece em 12% dos casos — ele promete o dobro do que entrega. A escala de Platt (uma logística ajustada sobre o próprio logit, na validação) baixa o ECE de 0,0254 para 0,0042, seis vezes. No meio, a floresta, que já estava quase calibrada — 0,0076 para 0,0041. À direita, o que a correção não mudou.
Naive bayes, no testeComo saiuApós Platt
ECE0,02540,0042
Probabilidade média declarada0,04100,0221
AUC-ROC0,82140,8214
Precisão média (AP)0,25560,2556
A taxa base real é 0,0248. O modelo bruto declarava 0,0410 em média — quase o dobro de fraude do que existe. E as duas métricas de ordenação são idênticas até a quarta casa: Platt é monótona, e transformação monótona não reordena nada.
Quais modelos precisam disso

Um modelo treinado minimizando log loss — regressão logística, rede neural com entropia cruzada — já sai razoavelmente calibrado, porque a log loss é uma regra de pontuação própria: ela é minimizada dizendo a verdade. Quem precisa de correção são os que não otimizam isso: naive bayes (independência falsa entre variáveis empurra as probabilidades para os extremos), SVM, e florestas em menor grau. Ajuste sempre na validação, nunca no treino — no treino o modelo já acertou tudo e a curva sai plana.

Checkpoint 5 · vale a pena calibrar?

Nenhuma métrica de ordenação melhorou com Platt. Um colega conclui que a calibração foi inútil. Onde ele está errado — e em que situação ele estaria certo?

resposta

Ele está errado sempre que a probabilidade é usada como número, e não como ordem. O bloco 4 é o exemplo imediato: o limiar por custo é uma probabilidade, então um modelo que infla as suas erra o corte. O mesmo vale para qualquer conta de valor esperado, para uma fila de triagem cortada por confiança, e para uma probabilidade entregue a outro sistema ou a uma pessoa.

Ele estaria certo se o consumo fosse puramente ordinal: revisar os 100 alertas mais prováveis do dia, ranquear resultados. Nesse regime só a ordem importa, e a calibração — por ser monótona — não muda nada mesmo.

Bloco 6 · 15 min

Regressão: a mesma disciplina, outro alfabeto

Dados reais agora — 442 pacientes diabéticos, prevendo a progressão da doença em um ano. As perguntas não mudam: contra o quê, e o que o resumo esconde?

image/svg+xml Matplotlib v3.10.9, https://matplotlib.org/
À esquerda, previsto contra observado: a nuvem acompanha a diagonal, mas larga. À direita, o gráfico que decide se você acredita no resumo — os resíduos contra o previsto. Aqui eles são uma faixa sem estrutura, o que é a licença para reportar um único RMSE.
ModeloRMSEMAEMedAER²RMSE/MAE
Regressão linear55,744,640,10,3931,25
Linha de base: prever a média71,459,554,10,0001,20
Linha de base: prever a mediana72,559,152,0−0,0291,23
O R² de 0,393 é a comparação com a linha de base da média — R² = 0 é exatamente prever a média sempre. Reportar as duas linhas junto não é redundância: é o que transforma "0,393" em "erra 22% menos do que o chute mais burro possível".

RMSE/MAE = 1,25 é o valor esperado para erro gaussiano bem comportado, e concorda com o gráfico de resíduos. Fosse 2 ou 3, a mesma tabela mereceria desconfiança: o erro estaria concentrado em poucos casos grandes, e o RMSE médio não descreveria nenhum paciente típico. O pior resíduo desta amostra é de 164,6 — três vezes o RMSE, num alvo cuja faixa é de 25 a 346.

Checkpoint 6 · o R² subiu, o modelo melhorou?

Você aplica o mesmo modelo a um segundo hospital e o R² sobe de 0,39 para 0,71, com RMSE de 56 para 58. O modelo ficou melhor?

resposta

Não. Ficou ligeiramente pior em erro absoluto (RMSE 56 → 58), e o R² subiu porque a população do segundo hospital é mais heterogênea — o denominador do R² é a variância do alvo naquele conjunto. Prever a média ali é um chute pior, então superá-la rende mais.

Daí a regra: R² compara você com uma linha de base dentro do mesmo conjunto; ele não compara conjuntos. Entre populações diferentes, compare RMSE — que está em unidades do problema — e leve a linha de base junto para que o leitor veja o que mudou.

Bloco 7 · 20 min · em duplas

Sua própria avaliação

A parte da aula sem resposta impressa.

  1. Reproduza. Rode o código do apêndice B e confirme os números do bloco 3 (AUC 0,888 e AP 0,553 para a floresta). Se não bater, resolva isso antes de seguir.
  2. Mude a taxa base. Refaça o conjunto com weights=[0.999, 0.001] — 0,1% de fraude. Meça AUC e AP de novo. Qual das duas se mexeu? Quanto? Escreva a razão AP / taxa base nos dois cenários.
  3. Sua matriz de custo. Escolha um problema que você conhece (spam, triagem médica, moderação, crédito) e atribua custos aos dois erros. Calcule o limiar da fórmula, ache o mínimo empírico na validação, e reporte o quanto o 0,5 custaria.
  4. Quebre a calibração. Treine um modelo que precise dela — GaussianNB, ou uma floresta bem rasa — e meça ECE antes e depois de Platt. Confirme que AUC e AP não mudaram nem na quarta casa.
  5. Uma medida no teste. Escolha uma configuração final inteira (modelo + limiar + calibração) usando só a validação, meça no teste uma vez, e escreva as três frases que você colocaria num relatório: o número, contra qual linha de base, e com qual limiar e por quê.
Para entregar

Uma página: a tabela AUC × AP nas duas taxas base, a sua matriz de custo com o limiar que ela implica, o ECE antes e depois, e — o que mais conta — a frase final de relatório, com a linha de base ao lado do número.

Apêndice A

Tabela de decisão

Se a sua pergunta éUseNão use, e por quê
O modelo aprendeu?Métrica escolhida menos a da linha de base trivialAcurácia sozinha: com 2,5% de positivos, o return 0 tira 97,5%.
Qual modelo é melhor, com classe rara?Precisão média (AP), com a taxa base ao ladoAUC-ROC: comprime as diferenças e, aqui, chega a inverter a ordem de dois modelos.
Qual modelo é melhor, com classes equilibradas?AUC-ROC serve bem—
Onde cortar?Custo dos dois erros: p* = CFP/(CFP+CFN), refinado por varredura na validação0,5, que é o padrão da biblioteca; máximo F1, que assume que os dois erros doem igual.
Posso usar a probabilidade numa conta?ECE e curva de confiabilidade; corrija com Platt ou temperatura na validaçãoConfiar no número porque a AUC é alta — AUC não vê calibração.
Quanto erra o modelo de regressão?RMSE nas unidades do alvo, com a linha de baseR² entre conjuntos diferentes: o denominador dele muda com a população.
Posso acreditar neste RMSE?Gráfico de resíduos; RMSE/MAE como alarme baratoNenhum resumo sozinho — quatro erros diferentes dão o mesmo RMSE.
As três perguntas que valem por metade da aula
  1. Quanto tira o modelo trivial? Se ninguém disse, o número não significa nada.
  2. Qual é a taxa base? Ela decide quais métricas mentem.
  3. Que decisão esse número vai tomar? Se a resposta for "nenhuma", você está reportando enfeite.

Apêndice B

Código completo

O arquivo que gerou todos os números e figuras desta página, em scripts/handouts/metricas_fraude.py.

MODELS = {}
for name, mdl, scaled in [
        ("floresta", RandomForestClassifier(n_estimators=200, min_samples_leaf=3, random_state=0), False),
        ("logística", LogisticRegression(max_iter=2000), True),
        ("naive bayes", GaussianNB(), True)]:
    m = mdl.fit(Z_tr if scaled else X_tr, y_tr)
    MODELS[name] = dict(
        val=m.predict_proba(Z_val if scaled else X_val)[:, 1],
        test=m.predict_proba(Z_te if scaled else X_te)[:, 1])

def counts(y_true, p, thr):
    pred = (p >= thr).astype(int)
    tp = int(((pred == 1) & (y_true == 1)).sum())
    fp = int(((pred == 1) & (y_true == 0)).sum())
    fn = int(((pred == 0) & (y_true == 1)).sum())
    tn = int(((pred == 0) & (y_true == 0)).sum())
    return tp, fp, fn, tn


def metrics(y_true, p, thr):
    tp, fp, fn, tn = counts(y_true, p, thr)
    prec = tp / (tp + fp) if tp + fp else 0.0
    rec = tp / (tp + fn) if tp + fn else 0.0
    f1 = 2 * prec * rec / (prec + rec) if prec + rec else 0.0
    return dict(thr=thr, tp=tp, fp=fp, fn=fn, tn=tn, precision=prec, recall=rec, f1=f1,
                accuracy=(tp + tn) / len(y_true))


def platt(p_fit, y_fit, p_apply):
    """Escala de Platt: uma regressão logística sobre o próprio logit."""
    z = np.log(np.clip(p_fit, 1e-9, 1 - 1e-9) / (1 - np.clip(p_fit, 1e-9, 1 - 1e-9)))
    lr = LogisticRegression(max_iter=1000).fit(z.reshape(-1, 1), y_fit)
    za = np.log(np.clip(p_apply, 1e-9, 1 - 1e-9) / (1 - np.clip(p_apply, 1e-9, 1 - 1e-9)))
    return lr.predict_proba(za.reshape(-1, 1))[:, 1]


def reliability(p, y_true, bins=12):
    edges = np.linspace(0, 1, bins + 1)
    xs, ys, ns = [], [], []
    for lo, hi in zip(edges[:-1], edges[1:]):
        m = (p > lo) & (p <= hi)
        if m.sum() >= 10:
            xs.append(p[m].mean()); ys.append(y_true[m].mean()); ns.append(int(m.sum()))
    return np.array(xs), np.array(ys), np.array(ns)


def ece(p, y_true, bins=12):
    edges, e = np.linspace(0, 1, bins + 1), 0.0
    for lo, hi in zip(edges[:-1], edges[1:]):
        m = (p > lo) & (p <= hi)
        if m.sum():
            e += m.mean() * abs(y_true[m].mean() - p[m].mean())
    return float(e)
O mesmo, com o que o scikit-learn já traz pronto
from sklearn.metrics import (average_precision_score, roc_auc_score,
                             precision_recall_curve, brier_score_loss)
from sklearn.calibration import CalibratedClassifierCV, calibration_curve

ap  = average_precision_score(y_val, p_val)     # a métrica do bloco 3
prec, rec, thr = precision_recall_curve(y_val, p_val)
cal = CalibratedClassifierCV(modelo, method="sigmoid", cv="prefit").fit(X_val, y_val)
x, y_ = calibration_curve(y_te, p_te, n_bins=12)   # a curva do bloco 5

Duas ressalvas. CalibratedClassifierCV com cv="prefit" precisa de um conjunto que o modelo não viu — passar o treino aqui é o erro mais comum. E o ECE não vem pronto: são as quatro linhas do apêndice acima, e o número depende do número de faixas, então reporte-o junto.

Apêndice C

Respostas dos checkpoints

#PerguntaResposta em uma linha
1Quantas fraudes passam com recall 30%?69 das 99. Para pegar metade delas, os falsos positivos crescem — as distribuições se sobrepõem, e não há corte que separe sem custo.
2O F1 escolhe bem o limiar?Só quando precisão e recall doem igual. Alerta barato → limiar baixo; alerta tóxico → limiar alto.
3AUC-ROC ou AP no slide?AP, com a taxa base ao lado: é a que responde "dos alertas que vou revisar, quantos são fraude?" — e aqui as duas invertem a ordem de dois modelos.
4A fraude cai de 250 para 50: o limiar?Sobe, de 0,020 para 0,091. O limiar é parâmetro do negócio, não do modelo — muda sem retreino.
5Calibrar adiantou, se nada de ordenação mudou?Adiantou para tudo que usa a probabilidade como número — o limiar por custo, à frente. Para consumo puramente ordinal, não muda nada mesmo.
6R² sobe de 0,39 para 0,71 e o RMSE piora.O modelo piorou. R² compara com a média daquele conjunto; entre populações, compare RMSE.

Este handout acompanha as páginas de 8.1 Classificação e 8.2 Regressão, que trazem os simuladores interativos — inclusive um em que a temperatura de calibração se ajusta na sua frente, e outro com quatro modelos que compartilham o mesmo RMSE.