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 pergunta | O número que responde | O que dá errado quando você pula |
|---|---|---|
| O modelo aprendeu alguma coisa? | Comparação com a linha de base trivial | Você 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-ROC | Você escolhe o modelo errado — e neste handout as duas métricas discordam. |
| Onde cortar? | O custo dos dois erros | Fica no 0,5 de fábrica e paga o dobro. |
| Posso confiar na probabilidade? | ECE e a curva de confiabilidade | Toda conta de valor esperado feita em cima dela sai errada. |
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ê.
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:
| Limiar | Acurácia | Precisão | Recall | F1 | Fraudes perdidas | Alertas falsos |
|---|---|---|---|---|---|---|
| 0,50 (o padrão) | 98,1% | 83,3% | 30,3% | 0,444 | 69 | 6 |
| 0,15 | 97,6% | 50,4% | 60,6% | 0,550 | 39 | 59 |
| 0,03 | 86,3% | 12,9% | 78,8% | 0,222 | 21 | 526 |
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:
| Modelo | AUC-ROC | Precisão média (AP) | Ordem pela AUC | Ordem pela AP |
|---|---|---|---|---|
| Floresta aleatória | 0,888 | 0,553 | 1º | 1º |
| Naive bayes | 0,821 | 0,256 | 2º | 3º |
| Regressão logística | 0,809 | 0,276 | 3º | 2º |
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.
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:
| Limiar escolhido por | Valor | Custo na validação | Acima do mínimo |
|---|---|---|---|
| Mínimo medido na validação | 0,057 | 7 855 | — |
| Fórmula CFP/(CFP+CFN) | 0,020 | 8 940 | +14% |
| Máximo F1 | 0,197 | 12 445 | +58% |
| O padrão 0,5 | 0,500 | 16 305 | +108% |
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.
| Naive bayes, no teste | Como saiu | Após Platt |
|---|---|---|
| ECE | 0,0254 | 0,0042 |
| Probabilidade média declarada | 0,0410 | 0,0221 |
| AUC-ROC | 0,8214 | 0,8214 |
| Precisão média (AP) | 0,2556 | 0,2556 |
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?
| Modelo | RMSE | MAE | MedAE | R² | RMSE/MAE |
|---|---|---|---|---|---|
| Regressão linear | 55,7 | 44,6 | 40,1 | 0,393 | 1,25 |
| Linha de base: prever a média | 71,4 | 59,5 | 54,1 | 0,000 | 1,20 |
| Linha de base: prever a mediana | 72,5 | 59,1 | 52,0 | −0,029 | 1,23 |
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.
- 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.
- 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. - 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.
- 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. - 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 é | Use | Não use, e por quê |
|---|---|---|
| O modelo aprendeu? | Métrica escolhida menos a da linha de base trivial | Acurá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 lado | AUC-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ção | 0,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ção | Confiar 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 base | R² entre conjuntos diferentes: o denominador dele muda com a população. |
| Posso acreditar neste RMSE? | Gráfico de resíduos; RMSE/MAE como alarme barato | Nenhum resumo sozinho — quatro erros diferentes dão o mesmo RMSE. |
As três perguntas que valem por metade da aula
- Quanto tira o modelo trivial? Se ninguém disse, o número não significa nada.
- Qual é a taxa base? Ela decide quais métricas mentem.
- 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
| # | Pergunta | Resposta em uma linha |
|---|---|---|
| 1 | Quantas 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. |
| 2 | O F1 escolhe bem o limiar? | Só quando precisão e recall doem igual. Alerta barato → limiar baixo; alerta tóxico → limiar alto. |
| 3 | AUC-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. |
| 4 | A 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. |
| 5 | Calibrar 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. |
| 6 | R² 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.