Pular para o conteúdo
</>RoByte

Buscar cursos e aulas

Aulas do curso

Vídeo em breve

Por enquanto, esta aula está disponível só em texto — o vídeo entra assim que ficar pronto.

Avaliando modelos

Métricas de avaliação

MAE, RMSE e R² para regressão; matriz de confusão, precisão, recall e F1 para classificação; e por que a acurácia sozinha engana. · 18 min

Treinar um modelo é a parte fácil. A pergunta difícil é: ele é bom? E “bom” depende do problema. Esta aula apresenta as métricas que respondem essa pergunta de formas diferentes.

Métricas de regressão

Quando o alvo é um número, medimos o quanto as previsões erram:

Métrica O que mede
MAE (erro absoluto médio) Em média, quantas unidades o modelo erra
RMSE (raiz do erro quadrático médio) Parecido com o MAE, mas pune mais os erros grandes
R² Quanto da variação dos dados o modelo explica (1 é perfeito)
from sklearn.metrics import mean_absolute_error, mean_squared_error, r2_score

y_pred = modelo.predict(X_teste)

print(mean_absolute_error(y_teste, y_pred))
print(mean_squared_error(y_teste, y_pred) ** 0.5)   # RMSE
print(r2_score(y_teste, y_pred))

Um MAE de 15000 num modelo de preço de imóveis significa que, em média, o modelo erra R$ 15.000 para cima ou para baixo.

Métricas de classificação

Vamos usar o dataset de diagnóstico de tumores. Neste dataset, a classe 0 é maligno e a 1 é benigno:

from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
from sklearn.tree import DecisionTreeClassifier

X, y = load_breast_cancer(return_X_y=True)
X_treino, X_teste, y_treino, y_teste = train_test_split(
    X, y, test_size=0.3, random_state=42, stratify=y
)

modelo = DecisionTreeClassifier(max_depth=4, random_state=42)
modelo.fit(X_treino, y_treino)
y_pred = modelo.predict(X_teste)

Matriz de confusão

Ela mostra, para cada classe real, o que o modelo previu:

from sklearn.metrics import confusion_matrix

print(confusion_matrix(y_teste, y_pred))
# [[ 58   6]      linha 0: tumores malignos reais
#  [  4 103]]     linha 1: tumores benignos reais

Os números acima são só ilustrativos, o seu resultado pode variar um pouco. A diagonal são os acertos, e fora dela estão os erros. Os erros têm nomes importantes:

  • Falso positivo (FP): o modelo disse “sim” e era “não”.
  • Falso negativo (FN): o modelo disse “não” e era “sim”.

Precisão, recall e F1

Métrica Pergunta que responde Fórmula
Precisão Das vezes que previu “sim”, quantas acertou? VP / (VP + FP)
Recall De todos os “sim” reais, quantos encontrou? VP / (VP + FN)
F1 Equilíbrio entre precisão e recall média harmônica das duas
from sklearn.metrics import classification_report

print(classification_report(y_teste, y_pred))

O classification_report mostra precisão, recall e F1 de cada classe de uma vez.

Dica

Qual métrica priorizar depende do custo de cada erro. Num exame de câncer, deixar passar um tumor maligno (falso negativo) é muito mais grave que um alarme falso, então o recall da classe maligna é o que importa. Num filtro de spam, marcar um e-mail importante como spam (falso positivo) é o pior caso, então a precisão pesa mais.

Por que a acurácia sozinha engana

Imagine um sistema que detecta falhas raras num motor, em que só 5% das leituras são falhas. Um “modelo” que sempre responde “sem falha” tem 95% de acurácia e é completamente inútil, porque nunca detecta nada. É o problema das classes desbalanceadas, e a acurácia esconde ele.

Atenção

Sempre que as classes forem desbalanceadas, confie mais em precisão, recall e F1 do que na acurácia, e olhe a matriz de confusão.

Exercícios

Exercício

1. Aquecimento. Dada a matriz de confusão [[50, 10], [5, 35]] (linhas: real, colunas: previsto), calcule na mão a acurácia e depois confira com accuracy_score.

Exercício

2. Escolhendo a métrica. Para cada situação, diga se você priorizaria precisão ou recall e por quê: (a) um robô que detecta obstáculos à frente para frear; (b) recomendar filmes; (c) um alarme de incêndio.

Exercício

3. Desafio. Monte um problema desbalanceado: y com 950 zeros e 50 uns (np.array([0] * 950 + [1] * 50)) e X = np.zeros((1000, 1)). Treine um DummyClassifier(strategy="most_frequent") do sklearn.dummy e calcule a acurácia e o recall da classe 1 (recall_score). O que os dois números dizem sobre esse “modelo”?