(+351) 21 24 10006  ·  info@bconcepts.pt
Carnaxide, Lisboa

Como interpretar a matriz de confusão em Machine Learning

João Barros 04 de July de 2026 4 min de leitura

Depois de treinar um modelo de classificação, a pergunta mais importante é simples: onde é que ele acerta e onde é que erra? A matriz de confusão responde a isso num único quadro e é a base para calcular métricas como accuracy, precision e recall. Aprender a interpretar a matriz de confusão em Machine Learning evita a armadilha de confiar apenas na accuracy, que muitas vezes engana.

Pré-requisitos

  • Python 3 instalado no teu computador.
  • As bibliotecas scikit-learn e matplotlib (instala com pip install scikit-learn matplotlib).
  • Noções básicas de classificação: um modelo que prevê uma de duas classes (0 ou 1).
  • Não precisas de dados próprios, porque vamos gerar um conjunto de exemplo.

Passo 1: Treinar um modelo de classificação simples

Primeiro precisamos de um modelo e de previsões para analisar. Para o exemplo ser reproduzível, geramos um conjunto de dados binário com make_classification e treinamos uma regressão logística. O random_state garante que obténs exatamente os mesmos números deste tutorial.

from sklearn.datasets import make_classification
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression

# Binary dataset with 30% of class 1 (imbalanced)
X, y = make_classification(n_samples=1000, n_features=10, n_informative=5,
                           weights=[0.7, 0.3], random_state=42)

# Split into train (80%) and test (20%)
X_treino, X_teste, y_treino, y_teste = train_test_split(
    X, y, test_size=0.2, random_state=42)

modelo = LogisticRegression(max_iter=10000)
modelo.fit(X_treino, y_treino)

Passo 2: Gerar a matriz de confusão

Com o modelo treinado, fazemos previsões sobre os dados de teste e comparamo-las com os valores reais. A função confusion_matrix devolve uma tabela que cruza o que aconteceu na realidade com o que o modelo previu.

from sklearn.metrics import confusion_matrix

y_previsto = modelo.predict(X_teste)
matriz = confusion_matrix(y_teste, y_previsto)
print(matriz)

Neste exemplo, o resultado é:

[[127   6]
 [ 35  32]]

Passo 3: Ler os quatro quadrantes da matriz de confusão

Numa classificação binária, as linhas representam a classe real e as colunas a classe prevista pelo modelo. Cada célula tem um nome e um significado concreto:

  • Verdadeiros Negativos (VN) = 127: eram classe 0 e o modelo acertou (canto superior esquerdo).
  • Falsos Positivos (FP) = 6: eram classe 0, mas o modelo disse 1 (alarme falso).
  • Falsos Negativos (FN) = 35: eram classe 1, mas o modelo disse 0 (casos reais que escaparam).
  • Verdadeiros Positivos (VP) = 32: eram classe 1 e o modelo acertou (canto inferior direito).

Podes extrair os quatro valores diretamente para variáveis com ravel(), o que é útil para calcular as métricas a seguir:

vn, fp, fn, vp = matriz.ravel()
print(vn, fp, fn, vp)   # 127 6 35 32

Passo 4: Calcular accuracy, precision e recall

A partir dos quatro números saem as métricas essenciais. Repara como cada uma conta uma história diferente sobre o mesmo modelo:

  • Accuracy = (VP + VN) / total = (32 + 127) / 200 = 0,80. A percentagem total de acertos.
  • Precision = VP / (VP + FP) = 32 / 38 = 0,84. Das vezes que o modelo previu 1, quantas estavam certas.
  • Recall = VP / (VP + FN) = 32 / 67 = 0,48. Dos casos reais da classe 1, quantos o modelo apanhou.

Não precisas de fazer estas contas à mão: o scikit-learn calcula tudo de uma vez com classification_report.

from sklearn.metrics import classification_report
print(classification_report(y_teste, y_previsto))

Repara agora no ponto mais importante deste exemplo: a accuracy é de 80%, o que parece bom, mas o recall da classe 1 é apenas 48%. Ou seja, o modelo falha mais de metade dos casos positivos reais. É exatamente este tipo de erro que a matriz de confusão revela e que a accuracy sozinha esconde.

Passo 5: Visualizar a matriz de confusão

Um gráfico torna a leitura imediata, sobretudo para partilhar com colegas ou colocar num relatório. O ConfusionMatrixDisplay desenha a mesma tabela com cores a partir das previsões.

import matplotlib.pyplot as plt
from sklearn.metrics import ConfusionMatrixDisplay

ConfusionMatrixDisplay.from_predictions(y_teste, y_previsto)
plt.show()

Verificar o resultado

Para confirmar que está tudo certo, soma as quatro células: 127 + 6 + 35 + 32 = 200, que é exatamente o número de exemplos de teste. Se a soma bater certo com o tamanho do conjunto de teste, a matriz está bem construída. Compara também os valores de precision e recall que calculaste à mão com os que aparecem no classification_report: devem coincidir até à segunda casa decimal.

Conclusão

Com estes passos passaste de uma única percentagem para uma leitura completa do comportamento do modelo, distinguindo os erros que custam mais (neste caso, os falsos negativos). O próximo passo natural é experimentar ajustar o limiar de decisão (threshold) ou olhar para o F1-score, que equilibra precision e recall, e depois repetir a análise para problemas com mais do que duas classes. Qual das métricas é mais crítica no teu problema: evitar falsos positivos ou não deixar escapar falsos negativos?