Pular para o conteúdo principal

Tutorial: curva precisão-recall em Python

Aprenda a implementar e interpretar curvas precisão-recall em Python e descubra como escolher o limiar certo para atingir seu objetivo.
· 14 min leer

Explore com IA

Algoritmos de machine learning (ML) são cada vez mais usados para automatizar tarefas repetitivas e identificar padrões ocultos nos dados. Mas eles são inerentemente probabilísticos, ou seja, suas previsões nem sempre estão corretas. Por isso, você precisa de uma forma de estimar a confiabilidade do seu modelo de ML para gerar confiança nesses sistemas. 

Métricas de avaliação como acurácia, precisão, recall, erro quadrático médio (MSE), erro percentual absoluto médio (MAPE) e similares são amplamente usadas para medir o desempenho do modelo. Métricas diferentes permitem avaliar a performance por critérios e ângulos diferentes. 

Essas métricas também garantem que o modelo siga melhorando seu aprendizado na tarefa proposta. Afinal, se você não mede, não tem como melhorar o desempenho do sistema de ML.

Acurácia é uma métrica fácil de entender e funciona bem com conjuntos de dados balanceados, isto é, quando todas as classes têm representação semelhante. No entanto, fenômenos do mundo real raramente são distribuídos de forma uniforme; logo, datasets balanceados são difíceis de encontrar. A acurácia se preocupa principalmente se a maioria das instâncias foi identificada corretamente, independentemente da classe. Para eventos raros importantes, como uma transação fraudulenta ou um clique em um anúncio, a acurácia pode mascarar um modelo que simplesmente prevê tudo como classe negativa (sem fraude ou sem cliques). Devido a essas limitações, a acurácia não é a métrica mais adequada. Então, qual métrica usar para avaliar melhor nossos modelos?

Precisão e recall são métricas amplamente usadas para avaliar o desempenho de modelos de classificação desbalanceados, como no caso de previsão de churn de clientes. 

Precisão e recall, em resumo

Precisão indica o quão confiantes estamos de que uma classe positiva prevista é realmente positiva, enquanto o recall mede o quanto o modelo identifica dos exemplos positivos existentes no conjunto de dados. Observe que a classe positiva é a classe de interesse.

Na prática, precisão e recall são melhor compreendidos com a ajuda da matriz de confusão, que contém quatro termos-chave:

  • Verdadeiro positivo (TP): número de instâncias positivas corretamente identificadas
  • Falso positivo (FP): número de instâncias negativas incorretamente identificadas como positivas
  • Verdadeiro negativo (TN): número de instâncias negativas corretamente identificadas
  • Falso negativo (FN): número de instâncias positivas incorretamente identificadas como negativas

Precision-recall Representation

Representação criada pelo autor

Precisão e recall são expressões matemáticas desses quatro termos, em que:

Precisão é a proporção de TP sobre todas as previsões positivas (TP+FP). Recall é a proporção de TP sobre todas as instâncias realmente positivas (TP+FN).

Podemos simplificar usando a notação a seguir, destacando a diferença entre as duas. Essencialmente, ambas têm o mesmo numerador, que é a interseção entre os positivos reais e os positivos previstos, ou seja, TP.

Precision Recall Accuracy

Imagem por Shruti Saxena

O diferenciador está no denominador: a precisão considera todas as instâncias previstas como positivas (TP+FP), enquanto o recall considera todas as instâncias realmente positivas (TP+FN). 

Intuição por trás de precisão e recall 

Não é à toa que a matriz de confusão tem esse nome – ela realmente confunde quando tentamos entender esses conceitos pela primeira vez. 

Vamos internalizar com um exemplo. Imagine que você tem uma siderúrgica onde a fábrica extrai ferro do minério e o mistura com outros minerais e elementos (às vezes involuntariamente). Focando na extração, você tem algumas escolhas quanto à pureza do metal extraído e ao lixo gerado no processo, conforme abaixo:

Cenário 1: você quer priorizar apenas a pureza do ferro extraído, sem se importar com quanto metal é desperdiçado no processo.

Cenário 2: você quer maximizar a eficiência, isto é, a quantidade de ferro extraída por unidade de minério, sem considerar a pureza do metal extraído.

Cenário 3: você quer o melhor dos dois mundos, mantendo a pureza do metal extraído o mais alta possível enquanto reduz o desperdício (maximizando o ferro extraído por unidade de minério).

Pense no alto-forno ou no forno elétrico a arco como opções de modelagem que geram resultados diferentes (pureza e desperdício). Suponha que um dos métodos forneça ferro 97,5% puro e perca 4% do ferro no resíduo. Assim, podemos definir nossa precisão como a fração de ferro puro no metal extraído, ou 97,5%, enquanto o recall é a quantidade de ferro extraída de todo o ferro disponível no minério, que é 96% (4% do ferro é desperdiçado).

Iron Extraction Process

Ilustração criada pelo autor

Digamos que você siga o segundo método porque quer ferro mais puro, o que, por sua vez, implica mais desperdício no processo. Suponha que, ao aumentar a pureza do ferro em 0,5% para 98%, o desperdício de metal aumente em 11%. Isso significa que o valor de recall correspondente à precisão de 98% cai para 85%. Essa troca entre recall e precisão mostra a relação inversa entre essas métricas.

Não seria ótimo conhecer todos os valores de precisão e os recalls correspondentes para decidir o que melhor atende ao seu objetivo?

A curva precisão-recall ajuda a fazer essa escolha, e você vai entendê-la a fundo nas próximas seções. Mas antes, vamos entender o conceito de limiar (threshold), que é central na PR curve. 

O conceito de limiar (threshold)

Vamos usar o exemplo de identificação de transações fraudulentas para entender como funciona um limiar (ou cutoff). A tabela abaixo tem quatro transações com IDs de 1 a 4; uma transação pode ser fraudulenta ou regular. O modelo de detecção de fraudes gera a probabilidade de a transação ser fraudulenta (coluna amarela), o que implicitamente indica a probabilidade de ser regular. 

Uma transação é prevista como fraudulenta se a probabilidade for maior que o limiar escolhido na coluna Probability of Fraud transaction; caso contrário, é considerada regular. 

Transaction ID

Probability of Fraud transaction

Probability of regular transaction

Is fraudulent? (Threshold = 0.9)

Is fraudulent? (Threshold = 0.5)

Is fraudulent? (Threshold = 0.4)

1

0.3

0.7

No

No

No

2

0.4

0.6

No

No

Yes

3

0.6

0.4

No

Yes

Yes

4

0.95

0.05

Yes

Yes

Yes

Quando aplicamos um limiar rigoroso como 0,9, as três primeiras transações são marcadas como regulares e a última é marcada como fraudulenta. Um limiar tão alto transmite confiança nas previsões, levando a um cenário de alta precisão. Em contrapartida, você sacrifica o recall do modelo ao deixar passar algumas fraudes.

Esse cenário não é desejável, apesar da alta precisão. Consegue imaginar por quê?

Porque o negócio acaba pagando um custo maior por deixar de identificar fraudes, que é justamente o objetivo do modelo. Note que o custo de uma transação fraudulenta é muito maior do que o custo de bloquear uma transação regular, isto é, os FPs. 

Agora, considere o outro extremo com um limiar baixo de 0,4, que marca as três últimas transações como fraudulentas. Um limiar tão liberal vai bloquear a maioria das transações, o que pode irritar muitos clientes. Sem falar no esforço adicional da equipe para revisar as transações sinalizadas e encontrar as fraudes reais.

Portanto, a empresa precisa definir métricas-alvo e seus valores desejados para buscar o melhor dos dois mundos, considerando os seguintes custos:

  • Custo de classificar uma transação fraudulenta como regular (falsos negativos)
  • Custo de classificar uma transação regular como fraudulenta (falsos positivos)

Voltando à definição de precisão, vemos que os falsos positivos estão no denominador da expressão matemática, o que significa que minimizar FPs maximiza a precisão. Da mesma forma, minimizar FNs maximiza o recall do modelo.

Logo, classificar uma transação como fraudulenta ou regular depende fortemente do valor do limiar.

O que é uma curva precisão-recall?

Uma curva precisão-recall ajuda você a decidir um limiar com base nos valores desejáveis de precisão e recall. Ela também é útil para comparar o desempenho de modelos diferentes por meio da “área sob a curva precisão-recall” (AUC).

Como vimos pela matriz de confusão, um modelo de classificação binária produz TP, FP, TN e FN para diversos valores de limiar, em que cada limiar gera um par correspondente de precisão e recall. 

Traçar o recall no eixo x e a precisão correspondente no eixo y gera uma curva PR com inclinação negativa. Ela representa o trade-off entre precisão (reduzir FPs) e recall (reduzir FNs) para um modelo. Considerando a relação inversa entre precisão e recall, a curva geralmente é não linear, indicando que aumentar uma métrica reduz a outra, mas essa redução pode não ser proporcional.

Precision-recall curve

Imagem de StackExchange

Suponha que uma organização escolha um recall mínimo aceitável de 98%. A precisão fica em 30% no ponto de interseção representado pela estrela marcada como “Low Threshold, Low Precision, High Recall”.  

Os outros dois pontos extremos representam casos em que o limiar é:

  • Muito baixo – alto recall, mas com custo de capital humano e clientes irritados
  • Muito alto – alta precisão, mas com custo de fraudes não detectadas e perda de reputação

Como usar a PR curve

Além de definir o cutoff alinhado ao objetivo de negócio, a área sob a curva precisão-recall de vários modelos ou algoritmos pode ser usada para comparar seu desempenho. Em geral, é mais informativo comparar modelos usando PR curves do que métricas isoladas de precisão, recall ou mesmo o F1-score (média harmônica de precisão e recall).

Precision-recall curve 2

Imagem de Stackoverflow

Essas métricas dependem do limiar: ao mudar o limiar, muda a distribuição de TP, FP e FN. Dois modelos podem ter desempenhos distintos para um mesmo limiar, o que torna a PR curve uma opção robusta para comparação. No gráfico acima, vemos duas PR curves de algoritmos diferentes no mesmo dataset – a AUC do algoritmo dois é maior que a do algoritmo um, tornando-o a melhor escolha para o problema.

Implementando a curva precisão-recall em Python

Agora que você já sabe o que são as curvas precisão-recall e para que servem, vamos criar uma curva precisão-recall em Python. 

Passo 1: importar os pacotes necessários do Python

Vamos usar um conjunto de dados para detecção de câncer de mama, onde “classe 1” representa diagnóstico de câncer e “classe 0” indica ausência de câncer.

A primeira importação carrega o dataset de “sklearn.datasets”, incluindo as variáveis independentes e a variável-alvo. Por ser um dataset relativamente simples para a maioria dos algoritmos, escolhemos o Naive Bayes, importado como “GaussianNB” do sklearn. 

Em seguida, importamos “precision_recall_curve”, que retorna diferentes limiares e seus valores correspondentes de precisão e recall.

from sklearn.datasets import load_breast_cancer
from sklearn.naive_bayes import GaussianNB
from sklearn.metrics import precision_recall_curve
from sklearn.model_selection import train_test_split
import matplotlib.pyplot as plt

Passo 2: preparar os dados de treino e teste

As variáveis independentes estão na chave “data” e a variável-alvo na chave “target” dentro do dicionário “data”. Depois, dividimos em conjuntos de treino e teste usando o parâmetro test_size com valor 0,3.

# Load model breast cancer data
data = load_breast_cancer()
X = data['data']
y = data['target']

Vamos observar a distribuição das classes positiva e negativa, ou seja, casos com e sem câncer de mama.

import numpy as np
unique, counts = np.unique(y, return_counts=True)
plt.pie(counts, labels=unique, autopct='%.0f%%');

Distribution of positive and negative class

Divida os dados em treino e teste usando o método train_test_split do módulo model_selection do sklearn.

X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=0)

Passo 3: treinamento do modelo

Os dados de treinamento são passados como argumentos para GaussianNB() para iniciar o treino. O objeto ajustado é então usado para obter as previsões na forma de probabilidades no conjunto de treino e de teste. 

# Fit a Naive Bayes model
clf = GaussianNB().fit(X_train, y_train)

Passo 4: gerar previsões

Gere probabilidades de previsão usando os dados de treino e teste, que serão usadas para obter precisão e recall em diferentes valores de limiar.

# Predict probability
y_prob_train = clf.predict_proba(X_train)[:,1]
y_prob_test = clf.predict_proba(X_test)[:,1]

Passo 5: plotar a PR curve

O método precision_recall_curve() recebe duas entradas – as probabilidades do conjunto de treino (y_prob_train) e os valores verdadeiros – e retorna três vetores: precisão, recall e limiares.

precision, recall, thresholds = precision_recall_curve(y_train, y_prob_train)
plt.fill_between(recall, precision)
plt.ylabel("Precision")
plt.xlabel("Recall")
plt.title("Train Precision-Recall curve");

Os vetores de precisão e recall são usados para plotar a PR curve em limiares variados, como abaixo:

Train Precision-recall curve

PR curve gerada pelo autor

A curva precisão-recall é melhor que a ROC?

A curva ROC é semelhante à PR curve, mas plota a taxa de verdadeiros positivos (TPR) vs a taxa de falsos positivos (FPR) para diferentes limiares. Já conhecemos a TPR: é só outro nome para recall. Então vamos focar na FPR, que indica a quantidade de classificações incorretas da classe negativa. No exemplo de fraude, é a porcentagem de transações regulares marcadas como fraudulentas.

True Positive Fals Positive

Imagem por Albert Um

Agora entendemos que o recall (TPR) é comum entre PR e ROC; a diferença está entre precisão e FPR, respectivamente. Vamos ver por que a PR curve costuma ser mais informativa.

Isso ocorre porque a PR curve traz insights mais significativos sobre a classe de interesse do que a ROC. No caso de transações fraudulentas, os verdadeiros negativos (TN) em datasets desbalanceados tendem a ser muito numerosos, tornando a FPR um valor minúsculo. Mas isso diz algo sobre o desempenho do modelo em prever fraudes?

Não! Por outro lado, usar a precisão como uma das métricas descreve o desempenho do modelo na classe positiva (fraudes). Isso indica se o modelo é mais conservador ou mais liberal ao marcar transações como fraudulentas.

O segundo grande problema da curva ROC é sua “imunidade” a dados desbalanceados. Pela figura acima, vemos que a FPR é uma métrica somente da classe negativa, o que significa que a variação em FP tende a ser proporcional à variação em FP+TN (todas as instâncias negativas). Assim, se a distribuição das classes muda, a ROC não muda tanto. Essa insensibilidade à distribuição de classes torna a PR curve uma aposta melhor que a ROC.

Considerações finais

Precisão e recall são métricas essenciais para avaliar o desempenho de modelos de classificação em machine learning. No entanto, o trade-off entre as duas depende do objetivo de negócio e é melhor resolvido por meio da PR curve. Neste artigo, você viu como interpretar a PR curve e escolher o limiar certo para atingir a meta do negócio. Também apresentamos um passo a passo de como plotá-la em Python e discutimos por que a PR curve costuma ser mais informativa do que a ROC.  

Temas

Relacionado