Machine Learning · Insper

Métricas de Classificação

Abordagem fundamental

Quais erros o modelo comete e como medir cada um

Dois erros, dois preços

Escape (falso negativo)

  • um câncer não detectado pode custar uma vida;
  • uma fraude aprovada custa o valor inteiro.

Alarme falso (falso positivo)

  • um exame de acompanhamento custa dinheiro e um susto;
  • um cartão bloqueado custa um telefonema.
A acurácia conta os dois como se fossem o mesmo. Escolher uma métrica é escolher qual erro você aceita cometer com mais frequência.

O caminho desta parte

  1. Contar os erros20 pacientes, quatro grupos, a matriz de confusão
  2. Acurácia não bastaa fração de acertos e o seu paradoxo
  3. Uma pergunta por métricaprecisão, revocação, especificidade e as outras: uma linha ou uma coluna cada
  4. Limiar e F1mover a linha troca um erro pelo outro; o F1 resume os dois
Cada etapa responde a uma pergunta: que erros o modelo comete? → a fração de acertos basta? → o que cada métrica pergunta? → onde traçar a linha?
Etapa 1 · Que erros o modelo comete?

O exemplo da aula: 20 pacientes

Um modelo deu a cada paciente um escore; exames posteriores revelaram quem estava doente. Dez doentes, dez saudáveis.

idescoredoenteidescoredoente
P010,951P100,451
P050,750P120,351
P080,600P150,201
………………
O modelo não responde "doente": ele dá um escore. Nós viramos escore em rótulo com um limiar, 0,5 por convenção.

Quatro grupos, quatro contagens

Os 20 pacientes no eixo do escore, separados pelo limiar 0,5
  • TP = 7 verdadeiro positivo: doente e marcado
  • FP = 2 falso positivo: saudável, marcado (alarme falso)
  • FN = 3 falso negativo: doente, não marcado (escape)
  • TN = 8 verdadeiro negativo: saudável, não marcado

As siglas vêm do inglês: true/false positive/negative.

Toda métrica da aula é uma razão entre estes quatro números: 7, 2, 3, 8.

A matriz de confusão

O layout padrão: real nas linhas, previsto nas colunas, positivo primeiro.

prev. doenteprev. saudável
doenteTP = 7FN = 3
saudávelFP = 2TN = 8

No scikit-learn, com labels=[1, 0]:


cm = confusion_matrix(y_true, y_pred, labels=[1, 0])
# [[7 3]      TP FN
#  [2 8]]     FP TN
tp, fn, fp, tn = cm.ravel()
      
Sem labels, o scikit-learn ordena os rótulos (0 primeiro) e devolve [[TN, FP], [FN, TP]]: o canto superior esquerdo vira TN. Trocar os argumentos transpõe a matriz e troca FP com FN sem aviso.
Etapa 2 · A fração de acertos basta?

Acurácia: a diagonal sobre o total

\[ \text{acurácia} = \frac{TP + TN}{\text{todos}} = \frac{7 + 8}{20} = 0{,}750 \]
  • Aqui as classes são equilibradas (10 e 10), então uma resposta constante marcaria 0,50: 0,75 é uma melhora real.
  • A acurácia é um bom resumo quando as classes são equilibradas e os dois erros custam o mesmo.
Tire qualquer uma das duas condições e ela engana.

O paradoxo da acurácia

1.000 pacientes, 10 deles doentes (prevalência de 1%):

modeloacuráciarevocação
sempre "saudável"0,9900,00
preguiçoso (acha 5 de 10, 10 alarmes falsos)0,9850,50
  • A resposta constante marca 99,0% e não encontra ninguém.
  • O modelo que ao menos acha metade dos doentes marca menos.
Em dados desbalanceados, a acurácia premia quem ignora a classe rara. Sempre imprima a baseline ao lado (DummyClassifier).

Simulador: uma matriz, todas as métricas

Preveja. Aperte o modelo preguiçoso (sensibilidade 50%, especificidade 99%, prevalência 1%). A acurácia dele vai superar a baseline que sempre prevê a maioria?

Etapa 3 · O que cada métrica pergunta?

Cada métrica lê uma linha ou uma coluna (1/2): as linhas

Revocação, especificidade e FPR: cada uma lê uma linha da matriz, a dos doentes ou a dos saudáveis; numerador em verde, denominador numa moldura azul

Verde = numerador; moldura azul = denominador. As linhas são a condição real: revocação, especificidade e FPR perguntam "dos que de fato eram doentes (ou saudáveis), quantos…?".

Cada métrica lê uma linha ou uma coluna (2/2): as colunas

Precisão e VPN leem uma coluna da matriz, a dos previstos doentes ou a dos previstos saudáveis; a acurácia lê a matriz toda

As colunas são a previsão: precisão e VPN perguntam "quando o modelo disse doente (ou saudável), acertou?". Sabendo quais células a métrica usa, você sabe o que ela mede e o que ela ignora.

Precisão e revocação

Precisão — a coluna dos marcados

\[ \frac{TP}{TP + FP} = \frac{7}{9} = 0{,}778 \]

Quando ele diz "doente", acerta? Ignora os escapes.

Importa quando agir sobre um alarme é caro: filtro de spam, cirurgia, equipe com 50 ligações por dia.

Revocação — a linha dos doentes

\[ \frac{TP}{TP + FN} = \frac{7}{10} = 0{,}700 \]

Dos doentes, quantos são pegos? Ignora os alarmes falsos.

Importa quando um escape é caro: rastreamento de câncer, fraude, trinca em avião.

Também chamadas de VPP (valor preditivo positivo) e de sensibilidade (a TPR, true positive rate, taxa de verdadeiros positivos), o eixo vertical da curva ROC (receiver operating characteristic).

Especificidade, FPR e VPN

Especificidade

\[ \frac{TN}{TN + FP} \] \[ = \frac{8}{10} = 0{,}800 \]

FPR

\[ \frac{FP}{FP + TN} \] \[ = \frac{2}{10} = 0{,}200 \]

= 1 − especificidade

VPN

\[ \frac{TN}{TN + FN} \] \[ = \frac{8}{11} = 0{,}727 \]
  • Especificidade (ou TNR, true negative rate) e FPR (false positive rate, taxa de falsos positivos) leem a linha dos saudáveis: dos 10 saudáveis, 8 foram deixados em paz e 2 receberam alarme falso.
  • O VPN (valor preditivo negativo) lê a coluna dos mandados para casa: dos 11 liberados, 8 estavam de fato saudáveis. É ele que importa quando é a resposta negativa que vira ação.

Tudo num lugar só

métricaperguntacélulasvalor
acuráciaquantas respostas estão certas?(7 + 8) / 200,750
precisão (VPP)quando diz "doente", acerta?7 / 90,778
revocação (TPR)dos doentes, quantos são pegos?7 / 100,700
especificidade (TNR)dos saudáveis, quantos ficam em paz?8 / 100,800
FPRdos saudáveis, quantos recebem alarme?2 / 100,200
VPNquando diz "saudável", acerta?8 / 110,727
O scikit-learn só tem precisão e revocação — e basta: a especificidade é a revocação da classe 0 e o VPN é a precisão da classe 0. Use pos_label=0.
Etapa 4 · Onde traçar a linha?

O limiar é uma decisão

limiarTPFPFNTNprecisãorevocação
0,394160,6920,900
0,572380,7780,700
0,751590,8330,500
O mesmo modelo nas três linhas: só a regra de decisão mudou. Precisão e revocação andam em sentidos opostos.

As duas curvas são escadas

Precisão e revocação dos 20 pacientes enquanto o limiar vai de 0 a 1

Elas só mudam quando o limiar cruza o escore de um paciente. A revocação só pode cair; a precisão tende a subir, com recuos (de 0,65 para 0,70 ela cai, porque o P07 é doente).

O modelo fornece a ordenação; o limiar diz quantos pacientes o hospital está disposto a encaminhar.

F1: um número a partir de dois

\[ F_1 = \frac{2 \cdot P \cdot R}{P + R} = \frac{2\,TP}{2\,TP + FP + FN} = \frac{14}{19} = 0{,}737 \]

\(P\) = precisão, \(R\) = revocação (recall). Repare no que não está ali: TN.

Três cortes dos 20 pacientes como barras entre precisão e revocação: a média fica no meio, o F1 perto da ponta menor
A média harmônica é puxada para o menor dos dois: pela média comum, marcar os 20 (0,750) ganharia do limiar 0,5 (0,739); pelo F1, não (0,667 contra 0,737).

A receita

  1. Monte a matriz antes de qualquer número único.
  2. Escolha a métrica pela pergunta, não pelo hábito.
  3. Imprima a baseline ao lado. Um escore sem referência não é resultado.
  4. Lembre que o limiar é seu e escolha-o na validação.
erro comumcorreção
ler a matriz padrão do scikit-learn (sem labels) como se TP fosse o canto superior esquerdopasse labels=[1, 0]
reportar só a acuráciaacurácia ao lado da baseline, mais revocação
comparar modelos por uma métrica sóum placar com várias
Lab fundamental · cerca de 40 min, em duplas

Triagem de diabetes: passos 1 a 7

  • 768 mulheres, 8 medidas, uma ferramenta que decide quem é encaminhado a um exame completo.
  • Notebook no Colab: nada para baixar. Salve uma cópia no seu Drive.
  • Em cada passo, responda o Preveja antes de rodar.
  • Simulações: de quem são os escapes? (passo 5) e e se o diabetes fosse raro? (passo 7).

Ritmo: passos 1 a 3 em 12 min; 4 a 6 em 15 min; passo 7 e a simulação em 13 min.