ML Atlas

Machine learning do zero · Aula 2.3 · 10 de 33 aulas prontas · 12 min

Limiar, ROC e PR: todos os limiares de uma vez

Em resumo

As curvas ROC e PR mostram todos os limiares de uma vez. Com uma classe rara, o ROC AUC quase não muda e o AP cai: os alarmes falsos comem a precisão.

Aquecimento Duas perguntas de aulas anteriores. Um minuto, e a aula nunca fica bloqueada.
Da aula 2.2: Avaliando um classificador: além da acurácia Um modelo de rastreamento deixa passar muitos cânceres, mas quase nunca dá alarme falso. Qual número está baixo?

Ver a resposta

Resposta certa: O recall, isto é, a fração dos cânceres detectados

O recall é a fração de positivos reais que foram pegos, então muitos casos perdidos significam recall baixo.

Da aula 2.1: Classificação: traçando uma fronteira Você sobe o limiar de 0,5 para 0,8. O que acontece com a fronteira?

Ver a resposta

Resposta certa: Ela se desloca sem girar; menos pinguins vão para a classe de probabilidade alta

Cada limiar corresponde a uma reta com a mesma direção; um limiar mais exigente a desloca para que só os casos confiantes passem.

Na aula 2.2 você movia um limiar e via a matriz de confusão mudar. Cada limiar é uma decisão diferente, embora as pontuações do modelo continuem as mesmas. Hoje você vai ver todos os limiares de uma vez, em duas curvas: ROC e precisão–sensibilidade (PR). Também vai conferir qual delas diz a verdade quando há poucos doentes. O modelo é fraco de propósito: uma regressão logística que vê só uma medida, a textura média do tumor, para que as curvas não grudem nos cantos.

Preveja, depois confira O mesmo modelo pontua as mesmas 357 biópsias benignas. Primeiro há 212 malignas (37% dos dados), depois só 19 (5%). O que acontece com o ROC AUC (a área sob a curva ROC), e o que acontece com o AP, a área sob a curva PR?
Qual é o seu grau de certeza?

Experimento interativo

Este experimento interativo funciona em um navegador com JavaScript ativado. O texto ao redor descreve o que ele mostra.

Ver a resposta

Resposta certa: O ROC AUC quase não muda (cerca de 0,77), enquanto o AP cai para cerca de 0,14

O ROC AUC é 0,773 com todas as malignas e 0,772 em média com 19 (em 200 sorteios de quais malignas ficam). O AP cai de 0,591 para 0,137 em média. O modelo não esqueceu nada; só as proporções das classes mudaram. A ROC não vê isso, a curva PR vê.

Experimente

  • Comece com 212 malignas e limiar 0,5. Leia a sensibilidade e a FPR e depois mova o limiar para 0,3. Para onde vai o ponto nas duas curvas?
  • Troque para 19 malignas com limiar 0,3. Há tantos alarmes falsos quanto há pouco. O que aconteceu com a precisão?
  • Compare o ROC AUC e o AP com 212, 40 e 19 malignas.

Depois de conferir no lab, vamos dar nome ao que você vê.

A ideia em poucas palavras

O modelo não diz “maligno” ou “benigno”. Ele dá uma pontuação de 0 a 1, e quem decide é um limiar. Cada limiar dá um par de números diferente: quantas malignas foram encontradas (sensibilidade) e quantas benignas receberam um alarme falso. A curva ROC desenha esses pares para todos os limiares de uma vez: na horizontal, a parcela de alarmes falsos entre as benignas (FPR); na vertical, a sensibilidade. Um limiar alto é o canto inferior esquerdo (poucos alarmes); um baixo, o canto superior direito (alarme em toda biópsia).

A curva precisão–sensibilidade (PR) mostra os mesmos limiares de outro jeito: na horizontal, a sensibilidade; na vertical, a precisão, ou seja, que parte dos alarmes está certa. A área sob a curva ROC é o ROC AUC; a área sob a curva PR é o AP (average precision). Cada um resume todos os limiares de uma vez, então não depende do limiar que você escolher.

Com as 569 biópsias o modelo tem ROC AUC de 0,773 e AP de 0,591. Chutar ao acaso daria ROC AUC de 0,5 e um AP igual à parcela de malignas, ou seja, 0,373. O modelo é claramente melhor que o acaso, mas está longe do ideal, que é 1.

Jak to policzono
  • Biópsias: Breast Cancer Wisconsin (Diagnostic), UCI, licença CC BY 4.0. 569 biópsias (357 benignas, 212 malignas). O modelo vê uma medida: a textura média do tumor.
  • Pontuações de validação cruzada em 5 partes (StratifiedKFold(5) no scikit-learn): cada biópsia é pontuada por um modelo que nunca a viu.
  • Classe mais rara: ficam as 357 benignas e 40 ou 19 malignas sorteadas. O gráfico mostra um sorteio; as médias são de 200 sorteios.
  • Modelo: padronização e regressão logística (C = 1).

Por que funciona

A ROC conta os alarmes falsos em relação às benignas: a FPR é o número de alarmes falsos dividido por 357. A sensibilidade conta os acertos em relação às malignas. Quando você tira malignas ao acaso, as duas frações continuam mais ou menos iguais, então a curva ROC e sua área quase não se mexem. Com limiar 0,3 o modelo dá alarme em 144 de 357 benignas (FPR 40,3%), haja 212 malignas ou 19.

A precisão conta os alarmes falsos em relação a todos os alarmes. Com 212 malignas e limiar 0,3 o modelo encontra 177, então a precisão é de 55,1%. Com 19 malignas ele encontra 17, e os 144 alarmes falsos continuam lá: a precisão cai para 10,6%, ou seja, 8,5 alarmes falsos por alarme certo. A curva PR cai junto com a precisão, e o AP vai de 0,591 para 0,137 em média. A linha do chute ao acaso na PR também desce, até a parcela de malignas: 0,051.

Não é sorte de um sorteio nem de um jeito de dividir os dados. Com 40 malignas (10%) o ROC AUC é 0,773 em média e o AP 0,232. No código abaixo, o mesmo modelo em 20 outras divisões tem, com 19 malignas, um AP abaixo da metade do obtido com todos os dados, todas as vezes.

Erro comum

Verdadeiro ou falso: “um ROC AUC alto significa poucos alarmes falsos”. Falso. O ROC AUC mede quão bem o modelo ordena: a probabilidade de uma biópsia maligna sorteada receber pontuação maior que uma benigna sorteada. Ele não diz quantos alarmes serão falsos, porque isso depende de quão rara é a classe. No lab, com 19 malignas o ROC AUC é 0,772 em média, quase o mesmo que com 212, e com limiar 0,3 há 8,5 alarmes falsos para cada certo. Quando a classe é rara, olhe a curva PR e a precisão no limiar que você vai usar de verdade.

Um aviso no sentido contrário: o AP também não é um número “só do modelo”. Ele depende da parcela da classe nos dados, então o AP de dois conjuntos com proporções diferentes não pode ser comparado diretamente. Compare o AP com a linha do chute ao acaso nos mesmos dados.

Quiz

Três perguntas para você se testar. Escolha uma resposta ou abra a resposta embaixo de cada pergunta. No teclado: as setas escolhem, Enter ou Espaço confirma.

1. O que a curva ROC mostra?
Ver a resposta

Resposta certa: A sensibilidade contra a parcela de alarmes falsos, para todos os limiares

Cada ponto da curva é um limiar. Um limiar alto é o canto inferior esquerdo; um baixo, o superior direito. A área sob a curva, o ROC AUC, resume todos os limiares num número: aqui 0,773.

2. As malignas são 5% em vez de 37%. O ROC AUC quase não se mexe. Por que o AP cai?
Ver a resposta

Resposta certa: Porque os mesmos alarmes falsos agora são uma parte bem maior de todos os alarmes

A FPR divide os alarmes falsos pelo número de benignas, que não muda. A precisão os divide por todos os alarmes. Com limiar 0,3 e 19 malignas há 144 alarmes falsos para 17 certos.

3. Quando a curva PR diz mais que a curva ROC?
Ver a resposta

Resposta certa: Quando a classe positiva é rara e o que importa é quantos alarmes estão certos

Com uma classe rara a curva ROC parece igual enquanto a precisão cai. No lab com 19 malignas o AP cai para 0,137 em média, embora o ROC AUC quase não se mexa.

Pontos-chave

  • A curva ROC e a curva PR mostram todos os limiares de uma vez; o limiar se escolhe depois, pelo custo dos erros.
  • O ROC AUC mede quão bem o modelo ordena e quase não depende das proporções das classes.
  • Quando a classe positiva é rara, os mesmos alarmes falsos comem a precisão: olhe a curva PR e o AP.
  • Compare o AP com a linha do chute ao acaso, a parcela da classe positiva nos mesmos dados.

Mais a fundo: fórmula, código, prática

A matemática

Com o limiar t, o modelo diz “maligno” quando sua pontuação s ≥ t. Então sensibilidade = TP / (TP + FN), FPR = FP / (FP + TN), precisão = TP / (TP + FP).

A FPR só tem benignas no denominador; a sensibilidade, só malignas. Se você tira malignas ao acaso, nenhuma das duas frações muda de forma sistemática, então a curva ROC fica. A precisão tem os dois tipos de alarme no denominador. Com limiar 0,3: 177 / (177 + 144) ≈ 0,551 com 212 malignas e 17 / (17 + 144) ≈ 0,106 com 19.

O ROC AUC é a probabilidade de uma maligna sorteada receber pontuação maior que uma benigna sorteada: AUC = P(s₊ > s₋), e os empates contam pela metade. O AP é a precisão média ponderada pelos saltos de sensibilidade: AP = Σₖ (Rₖ − Rₖ₋₁) · Pₖ. Pontuações ao acaso dão AUC 0,5 e um AP igual à parcela da classe positiva: 212 / 569 ≈ 0,373 ou 19 / 376 ≈ 0,051.

No código (Python)

O mesmo experimento no scikit-learn: pontuações de validação cruzada, ROC AUC e AP com 212, 40 e 19 malignas (médias de 1000 sorteios), e depois o mesmo em 20 outras divisões.

import numpy as np
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import StratifiedKFold, cross_val_predict
from sklearn.pipeline import make_pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import roc_auc_score, average_precision_score

X, y = load_breast_cancer(return_X_y=True)
X, y = X[:, [1]], 1 - y  # só a textura média, como no lab; 1 = maligno
model = make_pipeline(StandardScaler(), LogisticRegression())
def scores(cv):  # pontuações de validação: cada biópsia é pontuada por um modelo que nunca a viu
    return cross_val_predict(model, X, y, cv=cv, method="predict_proba")[:, 1]
ben, mal = np.flatnonzero(y == 0), np.flatnonzero(y == 1)
def rare(p, keep, draws, seed):  # as 357 benignas + `keep` malignas sorteadas, média dos sorteios
    rng = np.random.default_rng(seed)
    rows = [np.r_[ben, rng.choice(mal, keep, replace=False)] for _ in range(draws)]
    return np.mean([(roc_auc_score(y[i], p[i]), average_precision_score(y[i], p[i])) for i in rows], axis=0)
p = scores(StratifiedKFold(5))
print(f"212 malignant ({212 / 569:.0%}): ROC AUC {roc_auc_score(y, p):.3f}, AP {average_precision_score(y, p):.3f}")
for keep in (40, 19):
    auc, ap = rare(p, keep, 1000, 0)
    print(f"{keep} malignant ({keep / (357 + keep):.0%}), mean of 1000 draws: ROC AUC {auc:.3f}, AP {ap:.3f}")
r = []
for s in range(20):  # 20 outras formas de dividir os dados em 5 partes
    q = scores(StratifiedKFold(5, shuffle=True, random_state=s))
    r.append([roc_auc_score(y, q), average_precision_score(y, q), *rare(q, 19, 200, s)])
r = np.array(r)
print(f"20 other fold splits, 212 -> 19 malignant: ROC AUC {r[:, 0].mean():.3f} -> {r[:, 2].mean():.3f}, AP {r[:, 1].mean():.3f} -> {r[:, 3].mean():.3f}; AP below half in {(r[:, 3] < r[:, 1] / 2).sum()} of 20")

Saída

212 malignant (37%): ROC AUC 0.773, AP 0.591
40 malignant (10%), mean of 1000 draws: ROC AUC 0.773, AP 0.231
19 malignant (5%), mean of 1000 draws: ROC AUC 0.774, AP 0.140
20 other fold splits, 212 -> 19 malignant: ROC AUC 0.774 -> 0.775, AP 0.595 -> 0.140; AP below half in 20 of 20

Com todas as malignas os números são os mesmos do lab. Com 40 e 19 o código sorteia as malignas de outro jeito que o lab e faz 1000 sorteios em vez de 200, por isso as médias diferem na terceira casa decimal: AP 0,140 em vez de 0,137. Em 20 outras divisões o quadro é o mesmo: o ROC AUC fica, e o AP cai abaixo da metade todas as vezes.

Para quem pratica
  • No scikit-learn os números vêm de roc_auc_score e average_precision_score, e as curvas são desenhadas por RocCurveDisplay e PrecisionRecallDisplay. Calcule-os com pontuações de validação (cross_val_predict(..., method="predict_proba")), não com os dados de aprendizado.
  • Com uma classe rara (fraudes, doenças raras, falhas) informe o AP ao lado do ROC AUC, e ao lado do AP a linha do chute ao acaso, a parcela da classe positiva.
  • Uma curva é um cardápio de limiares. Escolha o limiar na validação pelo custo dos erros, por exemplo “sensibilidade de pelo menos 90% com a maior precisão possível”, e só depois confira no teste.
  • O ROC AUC de dois conjuntos com proporções diferentes pode ser comparado, mas não diz quantos alarmes serão falsos; o AP diz mais sobre isso, mas compare-o só com as mesmas proporções.

Vá mais fundo no Atlas

Verbetes da enciclopédia sobre as ideias desta aula: