Ir para o conteúdo

8.1. Classification

Um modelo não tem "uma acurácia". Ele tem uma família inteira de comportamentos, um para cada limiar que você poderia pôr na saída dele, e cada métrica resume essa família por um ângulo diferente. Escolher o resumo errado não é erro de arredondamento — costuma significar colocar em produção um modelo que não serve para a tarefa para a qual foi construído.

Por isso esta página é organizada em torno de uma única pergunta: que decisão você está tomando, e quanto custa errar? Toda métrica aqui é uma resposta a alguma versão dessa pergunta, e a questão é saber qual delas está fazendo a sua.

Por que a acurácia é uma armadilha

Comece com um exame de rastreio para uma doença que atinge 1 em cada 100 pessoas. Eis um modelo:

def prever(paciente):
    return "saudável"          # sempre

Em 10 000 pacientes ele acerta 9 900. 99% de acurácia — melhor que a maioria dos modelos publicados, e passaria em qualquer painel que reporte um número só. Ele também deixa passar todos os doentes, ou seja, como exame de rastreio não vale absolutamente nada.

Isso não é um exemplo forçado, é a situação normal. Fraude é rara. Falha de equipamento é rara. Raro é exatamente quando detectar importa, e a acurácia é mais enganosa justamente aí: a classe majoritária afoga o número que você está lendo.

A primeira pergunta diante de qualquer acurácia

Quanto o classificador trivial consegue? Se 95% dos seus dados são de uma classe, então 95% de acurácia é a nota de uma função constante. Qualquer métrica que um return 0 consiga bater não está medindo o seu modelo.

A matriz de confusão: de onde vem toda métrica

Tudo — toda métrica deste capítulo — são quatro números arranjados em um quadrado. Prever "doente" para quem está doente é um verdadeiro positivo; prever "doente" para quem está saudável é um falso positivo1.

Realmente positivo Realmente negativo
Previsto positivo VP — acerto FP — alarme falso (Tipo I)
Previsto negativo FN — perda (Tipo II) VN — rejeição correta

Os dois erros não são intercambiáveis, e o nome que eles têm no seu domínio já diz qual métrica procurar:

Domínio Um falso positivo é… Um falso negativo é… Qual dói mais
Rastreio de câncer uma biópsia desnecessária: custo, angústia um tumor mandado para casa sem diagnóstico FN, de longe
Filtro de spam um e-mail real perdido na caixa de spam uma mensagem chata na caixa de entrada FP, de longe
Detecção de fraude uma compra legítima recusada uma cobrança fraudulenta aprovada depende dos valores
Busca / recuperação um resultado irrelevante na primeira página um documento relevante nunca exibido em geral FP no topo

Precisão e revocação existem porque essas duas colunas precisam ser lidas separadamente:

\[ \text{Precisão} = \frac{VP}{VP + FP} \qquad\qquad \text{Revocação} = \frac{VP}{VP + FN} \]

As fórmulas se parecem e a diferença entre elas é o assunto inteiro, então leia-as como perguntas:

  • Precisãode tudo que sinalizei, quanto era real? Divide pelo que o modelo afirmou. É a métrica de quem vai agir sobre os alertas.
  • Revocaçãode tudo que é real, quanto eu peguei? Divide pelo que a realidade contém. É a métrica de quem vai sofrer com o que passou batido.

Um macete que sobrevive à prova

Olhe o denominador. Precisão é sobre os positivos previstos — as suas alegações. Revocação é sobre os positivos reais — a verdade. Um modelo que sinaliza um único caso e acerta tem 100% de precisão e revocação péssima. Um modelo que sinaliza todo mundo tem 100% de revocação e precisão igual à prevalência.

Tudo se move quando você move o limiar

Um classificador não devolve uma classe. Ele devolve um escore, e alguém escolheu um corte — geralmente 0,5, geralmente sem pensar. Essa escolha não faz parte do modelo; faz parte da decisão, e é aí que precisão e revocação trocam uma pela outra.

Abaixo: duas distribuições de escores, negativos em azul e positivos em laranja. Arraste o limiar e veja a matriz de confusão, todas as métricas e a posição nas duas curvas se moverem juntas.

Três experimentos, nesta ordem:

  1. Deixe a prevalência em 50% e varra o limiar. Precisão e revocação se movem em direções opostas — sempre. Abaixe o limiar e você pega mais positivos (revocação ↑) sinalizando mais inocentes (precisão ↓). Não existe ajuste em que as duas sejam máximas; existe só o ajuste que combina com os seus custos.
  2. Ponha a prevalência em 1% e deixe o limiar em 0,50. A acurácia marca cerca de 0,505 enquanto "prever sempre negativo" faz 0,990. O simulador avisa em vermelho. Toda métrica que mistura as duas classes em um número só faz isso.
  3. Mantenha o modelo fixo e mude apenas a prevalência. A ROC-AUC não se mexe — 0,921 a 50%, a 10% e a 1%. A PR-AUC desaba: 0,899 → 0,643 → 0,248. O modelo não piorou; a tarefa piorou, e só uma das duas curvas percebeu.

Esse terceiro experimento é o argumento inteiro sobre qual curva usar, então vale dizer por que ele acontece. A ROC põe a revocação contra a taxa de falsos positivos, \(FP/(FP+VN)\) — e o denominador dela são os negativos, que é exatamente a classe que cresce quando os positivos ficam raros. Dez alarmes falsos em um milhão de negativos é uma TFP invisível. A precisão divide esses mesmos dez alarmes falsos pelo punhado de positivos verdadeiros, onde eles são catastróficos. Quando os positivos são raros e os alarmes falsos são caros, a ROC vai lisonjear o seu modelo e a PR vai contar a verdade23.

O que a AUC-ROC realmente mede

Ela tem uma interpretação exata, e não é "acurácia média entre limiares":

\[ \text{AUC} = P\big(\,s(x^+) > s(x^-)\,\big) \]

a probabilidade de um positivo sorteado ao acaso receber um escore maior que um negativo sorteado ao acaso. AUC 0,92 quer dizer: pegue um doente e um saudável ao acaso, e o modelo os ordena corretamente 92% das vezes. Ela mede ordenação4, e nunca olha para o seu limiar nem para a calibração das probabilidades.

Esse é também o ponto cego dela. Um modelo pode ordenar perfeitamente (AUC = 1,0) e ainda assim devolver 0,51 para todo positivo e 0,49 para todo negativo — probabilidades inúteis, ordenação perfeita.

F1, e quando a média harmônica é a média errada

\[ F_1 = 2\cdot\frac{P \cdot R}{P + R} \]

A média harmônica é implacável de propósito: ela fica perto da menor das duas. Com \(P = 1{,}0\) e \(R = 0{,}01\) a média aritmética é uns respeitáveis 0,505, enquanto \(F_1 = 0{,}0198\). É essa a ideia — a F1 se recusa a deixar um modelo esconder uma revocação catastrófica atrás de uma precisão excelente.

Mas a F1 embute uma opinião específica — a de que precisão e revocação importam igualmente — e essa opinião costuma estar errada. O \(F_\beta\) deixa você declarar a sua:

\[ F_\beta = (1+\beta^2)\cdot\frac{P \cdot R}{\beta^2 P + R} \]

\(\beta\) é quantas vezes você se importa mais com revocação do que com precisão. O \(F_2\) (revocação com o dobro do peso) é padrão em rastreio médico; o \(F_{0,5}\) (precisão com o dobro do peso), em recomendação e busca. Se você consegue nomear a razão entre os custos, não deveria estar usando \(F_1\).

A F1 ignora completamente os verdadeiros negativos

Olhe a fórmula: VN não aparece em lugar nenhum. Isso é uma virtude quando os negativos são um oceano desinteressante (recuperação: os documentos que você não devolveu) e um defeito quando não são. Para um problema equilibrado, em que acertar os negativos faz parte do trabalho, o MCC (correlação de Matthews) usa as quatro células e é bem mais difícil de enganar:

\[ \text{MCC} = \frac{VP \cdot VN - FP \cdot FN}{\sqrt{(VP+FP)(VP+FN)(VN+FP)(VN+FN)}} \]

Ele vai de −1 a 1, e só fica alto quando o modelo vai bem nas duas classes5. Ponha o simulador em 1% de prevalência e compare F1 e MCC enquanto move o limiar.

Qual métrica, e por quê

A sua situação Use Porque
Classes equilibradas, erros custam o mesmo Acurácia É o que você quer dizer, e nada está escondido
Deixar passar um positivo é caro (doença, defeito, fraude) Revocação, \(F_2\) O custo está na coluna dos FN; otimize a coluna
Um alarme falso é caro (spam, moderação, alertas) Precisão, \(F_{0,5}\) O custo está na coluna dos FP
Positivos raros, comparando modelos PR-AUC, precisão média A ROC esconde os alarmes falsos atrás de um mar de VN
Comparando ordenadores, classes equilibradas ROC-AUC Independe do limiar e da prevalência
Você precisa da probabilidade, não do rótulo Log loss, Brier, curva de calibração Métricas de ordenação não checam se 0,8 significa 80%
Multiclasse desbalanceado Macro-F1, acurácia balanceada Dá voto às classes raras
Reportar um número para a chefia Matriz de confusão Dê quatro; um número sempre esconde algo

Multiclasse: micro, macro, ponderada

A partir de três classes, "a F1" deixa de existir — você precisa dizer como as F1 por classe são promediadas, e a escolha muda completamente a resposta. Pegue um problema de 1 000 amostras com classes A (900), B (90) e C (10):

Classe Precisão Revocação F1 Suporte
A 0,963 0,978 0,970 900
B 0,755 0,611 0,675 90
C 0,232 0,300 0,261 10

Esses são os números da matriz abaixo. Mova a revocação de qualquer classe e veja qual das três médias percebe:

Promediação Valor O que faz Quando usar
Micro 0,938 Junta todos os VP/FP/FN e calcula uma vez — aqui é igual à acurácia Você quer acerto global, cada amostra com peso igual
Macro 0,636 Média simples das F1 por classe — a classe rara pesa tanto quanto a A Você quer cada classe, sobretudo as raras
Ponderada 0,937 Média pesada pelo suporte — a A domina Raramente é o que se quer; reproduz o desbalanceamento

Releia os três números. A micro diz 0,938, a ponderada diz 0,937 — e o modelo acerta a classe C 3 vezes em 10. A macro é a única que reporta a falha, e a distância entre macro e ponderada mede diretamente o quanto você vai pior nas classes raras. Se for reportar um número em um problema multiclasse desbalanceado, reporte a macro.

Probabilidades, não apenas rótulos

Ordenar e cortar por limiar ignoram uma pergunta que importa em produção: quando o modelo diz 0,8, o evento acontece 80% das vezes? Um modelo pode ordenar perfeitamente e ainda assim ser sistematicamente confiante demais — e, se um humano ou um sistema a jusante consome esses números como probabilidades, o erro é silencioso e caro.

\[ \text{LogLoss} = -\frac{1}{N}\sum_{i=1}^{N}\big[y_i \log \hat{p}_i + (1-y_i)\log(1-\hat{p}_i)\big] \]

Pune erros confiantes sem piedade: prever 0,01 para algo que acontece custa \(-\log(0{,}01) = 4{,}6\), enquanto prever 0,4 custa \(0{,}92\). Um único erro confiante pode dominar a média inteira — e é por isso que ela é a perda de treino padrão, mas uma métrica de relatório instável.

\[ \text{Brier} = \frac{1}{N}\sum_{i=1}^{N}(\hat{p}_i - y_i)^2 \]

O erro quadrático médio das probabilidades6. Limitado a \([0,1]\), bem menos sensível a um único erro confiante que a log loss, e decompõe-se de forma limpa em calibração + refinamento. Bom para relatório.

Agrupe as previsões por probabilidade prevista e desenhe, para cada balde, a frequência observada. Um modelo calibrado fica sobre a diagonal. Redes profundas são famosas por serem confiantes demais7, e a correção padrão é o escalonamento por temperatura: divida os logits por um único escalar \(T\) ajustado em dados de validação. Isso não muda ordenação alguma — a AUC fica intacta — e pode reduzir o erro de calibração em uma ordem de grandeza.

Métricas e perdas não são a mesma coisa

A página que você está lendo é sobre métricas: o que se reporta e por que se escolhe um modelo. Uma perda é o que o gradiente descendente minimiza, e ela tem um requisito extra — precisa ser diferenciável. Acurácia, F1 e AUC são planas ou descontínuas em quase todo ponto, então nenhuma delas pode ser treinada diretamente.

É por isso que você treina com entropia cruzada e reporta F1. Quando as duas discordam — perda de validação subindo enquanto a F1 ainda melhora, por exemplo — em geral significa que a confiança está se degradando mais rápido que a ordenação, o que é um problema de calibração, não de ordenação.

O limiar é uma decisão de negócio, e tem fórmula

"Use 0,5" é um padrão herdado do argmax, não uma decisão. Se você consegue dizer quanto uma perda custa em relação a um alarme falso, o corte ótimo sai exato. Prever positivo em um caso cuja probabilidade verdadeira é \(p\) tem custo esperado \(C_{FP}(1-p)\); prever negativo custa \(C_{FN}\,p\). Vale sinalizar quando o primeiro for menor8, o que acontece quando

\[ p \;>\; p^\star = \frac{C_{FP}}{C_{FP} + C_{FN}} \]

Leia assim: se uma perda custa 9× um alarme falso, então \(p^\star = 1/10\) — sinalize tudo acima de 10%, não de 50%. O padrão 0,5 só está certo quando os dois erros custam o mesmo, o que quase nunca é o motivo pelo qual ele foi escolhido.

Repare no que o simulador não precisa: um modelo melhor. Mesmos pesos, mesmos escores, tudo igual — só o corte se move, e o custo esperado muda dezenas de por cento. Escolher o limiar costuma ser a melhoria mais barata disponível para um modelo já em produção, e é a que mais fica no valor padrão.

Como escolher um limiar honestamente

  1. Pergunte quanto custa cada erro. Dinheiro, horas, risco — qualquer unidade consistente serve.
  2. Calcule \(p^\star = C_{FP}/(C_{FP}+C_{FN})\), ou varra o limiar em uma partição de validação e minimize o custo diretamente, se não der para precificar exatamente.
  3. Confira antes se o modelo está calibrado. O \(p^\star\) é uma afirmação sobre probabilidades; sobre escores não calibrados ele é arbitrário.
  4. Reporte a matriz de confusão no limiar escolhido, não só a AUC. A AUC descreve a família inteira de modelos que você não colocou em produção.

No código

Toda métrica acima tem uma chamada no scikit-learn9, e a ordem das chamadas é o argumento desta página: primeiro ordene, depois escolha o limiar a partir dos custos, depois reporte a matriz.

from sklearn.metrics import (classification_report, confusion_matrix,
                             roc_auc_score, average_precision_score,
                             precision_recall_curve, brier_score_loss)

probs = model.predict_proba(X_val)[:, 1]

# sem limiar: os dois resumos, que respondem a perguntas diferentes
print("ROC-AUC:", roc_auc_score(y_val, probs))           # qualidade da ordenação
print("PR-AUC :", average_precision_score(y_val, probs))  # ordenação onde os positivos são raros

# escolha o limiar pelos custos, em dados de validação — nunca no teste
prec, rec, thr = precision_recall_curve(y_val, probs)
C_FP, C_FN = 1.0, 10.0
p_star = C_FP / (C_FP + C_FN)                             # = 0,0909...

pred = (probs >= p_star).astype(int)
print(confusion_matrix(y_val, pred))
print(classification_report(y_val, pred, digits=3))       # P/R/F1 por classe + macro e ponderada

# 0,8 é mesmo 80%?
print("Brier:", brier_score_loss(y_val, probs))

Dois erros que este código está arranjado para evitar

Ajustar o limiar no conjunto de teste. O corte é um parâmetro como qualquer outro; escolha em validação, reporte em teste — ou o seu número de teste é otimista.

Usar classification_report sem olhar a promediação. As últimas linhas trazem macro e ponderada. Leia a linha macro em problemas desbalanceados, e leia as linhas por classe antes de qualquer uma das duas.

Pontos-chave

  1. A acurácia responde "com que frequência eu acerto", que é a pergunta errada sempre que as classes estão desbalanceadas ou os dois erros custam valores diferentes. Compare-a sempre com a linha de base de prever sempre a classe majoritária.
  2. Toda métrica aqui são quatro números em um quadrado. Na dúvida, olhe a matriz de confusão; é o único relatório que não consegue esconder nada.
  3. A precisão divide pelo que você alegou; a revocação, pelo que é verdade. Qual delas importa decorre de qual erro dói.
  4. A ROC-AUC mede ordenação e independe da prevalência — o que é virtude ao comparar modelos e armadilha quando os positivos são raros. Ali a honesta é a PR-AUC.
  5. A F1 supõe que precisão e revocação importam igualmente. Se você sabe nomear a razão, use \(F_\beta\); se os negativos também importam, use MCC.
  6. No multiclasse, a promediação é a métrica. A macro é a que percebe as classes raras.
  7. Ordenar não é calibrar. Se um humano ou um sistema consome a probabilidade, meça-a — log loss, Brier, curva de calibração — e corrija com escalonamento por temperatura.
  8. O limiar não faz parte do modelo. Ele vem de \(p^\star = C_{FP}/(C_{FP}+C_{FN})\), e movê-lo costuma ser o ganho mais barato disponível.

Recursos Adicionais

  1. ROC and AUC, Clearly Explained! — Starmer, J., StatQuest. Constrói a curva ROC limiar a limiar, que é exatamente o que o primeiro simulador anima. Assista se a curva ainda parecer uma fórmula em vez de uma figura:

  2. Metrics and scoring: quantifying the quality of predictions — Guia do scikit-learn. A referência do que cada função de fato calcula, incluindo as regras de promediação que decidem o que f1_score significa no caso multiclasse.

  3. Classification: Accuracy, recall, precision — Google Machine Learning Crash Course. Uma segunda passada pelos mesmos compromissos com outros exemplos resolvidos, e uma boa fonte de exercícios.

Referências bibliográficas

As obras citadas ao longo do texto, na ordem em que aparecem:


  1. Matriz de confusão — Wikipedia. Um mapa útil das duas dezenas de nomes pelos quais as quatro células e suas razões atendem (sensibilidade, especificidade, VPP, VPN, TVP, TFP…). 

  2. Davis, J., & Goadrich, M. (2006). The Relationship Between Precision-Recall and ROC Curves — ICML. Prova que uma curva que domina no espaço ROC também domina no espaço PR, e que a recíproca é falsa — por isso a PR separa modelos que a ROC considera equivalentes. 

  3. Saito, T., & Rehmsmeier, M. (2015). The Precision-Recall Plot Is More Informative than the ROC Plot When Evaluating Binary Classifiers on Imbalanced DatasetsPLOS ONE 10(3). A versão medida do terceiro experimento acima. 

  4. Fawcett, T. (2006). An introduction to ROC analysisPattern Recognition Letters 27(8), 861–874. A referência padrão, incluindo a interpretação da AUC como ordenação e a visão de envoltória convexa para escolher pontos de operação. 

  5. Chicco, D., & Jurman, G. (2020). The advantages of the Matthews correlation coefficient (MCC) over F1 score and accuracy in binary classification evaluationBMC Genomics 21(6). Casos resolvidos em que F1 e acurácia parecem boas e o MCC não. 

  6. Brier, G. W. (1950). Verification of forecasts expressed in terms of probabilityMonthly Weather Review 78(1), 1–3. Vem da previsão do tempo, onde a pergunta sobre o que significa "70% de chance de chuva" apareceu cedo. 

  7. Guo, C., Pleiss, G., Sun, Y., & Weinberger, K. Q. (2017). On Calibration of Modern Neural Networks — ICML. Documenta que redes modernas são bem mais confiantes que as rasas que as precederam, e introduz o escalonamento por temperatura. 

  8. Elkan, C. (2001). The Foundations of Cost-Sensitive Learning — IJCAI. Deriva o limiar ótimo a partir da matriz de custos, e como reescalar probabilidades quando a prevalência de treino difere da de produção. 

  9. Metrics and scoring — Guia do scikit-learn. A definição exata de cada função usada acima, incluindo as regras de promediação micro/macro/ponderada.