exercício: montar uma matriz de confusão, achar a sensibilidade, a precisão, a acurácia e especifidade baseado em um set real.

Teste Genérico

Exemplo de Dataset Pequeno para Classificação Binária (gerado pelo gpt)

Dados:

AmostraPredição do ModeloClasse Verdadeira
1PositivoPositivo
2PositivoNegativo
3NegativoNegativo
4PositivoPositivo
5NegativoNegativo
6NegativoPositivo
7PositivoPositivo
8NegativoNegativo
9PositivoNegativo
10PositivoPositivo

Compilado:

Verdadeiros Positivos (VP): Amostras 1, 4, 7, 10 (4 casos)
Falsos Positivos (FP): Amostras 2, 9 (2 casos)
Verdadeiros Negativos (VN): Amostras 3, 5, 8 (3 casos)
Falsos Negativos (FN): Amostra 6 (1 caso)
PositivoNegativoTotal
PositivoVP = 4FN = 15
NegativoFP = 2VN = 35
Total6410

Métricas de Avaliação

  • Sensibilidade/Revocação -> taxa de verdadeiro positivo. ($S = \frac{VP}{VP + FN}$)
  • Especificidade do teste -> taxa de verdadeiro negativo. ($\xi = \frac{VN}{VN+PF}$)
  • Acurácia -> dentre todas, quais classificações estavam corretas. ($A = \frac{VP + VN}{VN + VP + FN + FP}$)
  • Precisão -> dentre as que foram ditas como corretas, quais são, de fato. ($P = \frac{VP}{VP+FP}$)

Sensibilidade -> $S = \frac{4}{4+1} = \frac45 = 0.8$ Especificidade -> $\xi = \frac{3}{3+1} = \frac34 = 0.75$ Acurácia -> $A = \frac{4+3}{4+3+1+2} = \frac7{10} = 0.7$ Precisão -> $P = \frac{4}{4+2} = \frac46 \approx 0.667$


Teste Real

Baseado no dataset Wine, um dataset que visa avaliar a qualidade de determinados vinhos, baseado em composição química. Evidentemente, são dados muito avançados para este teste, então pedi pra uma IA deixar apenas uma tabela com dados binários para que eu pudesse fazer uma avaliação mais simples. Temos um dataset binário com 107 amostras, onde:

A coluna 1 representa a porcentagem de álcool.
A coluna 13 representa a prolina (um aminoácido).

As classes foram mapeadas de forma binária:

0: Representa a classe original 1 (um tipo de vinho).
1: Representa a classe original 2 (outro tipo de vinho).

Amostragem parcial

Neste caso, vamos utilizar somente 9 amostras, para fazer o cálculo manual.

AmostraClasse preditadaClasse VerdadeiraÁlcoolProlina
00014.231065
10013.201050
20013.161185
31014.371480
40013.24735
50113.711285
61113.40915
70113.271280
81113.17520

Tabela

Foi utilizada uma escolha de predição sem critério, portanto, os números foram apenas gerados e colocados ali para serem comparados com o caso real do dataset.

01TOTAL
0415
1224
TOTAL639

Fazendo os cálculos:

  • Sensibilidade/Revocação: $S = \frac{4}{4 + 1} = 0.8$
  • Especificidade do teste: $\xi = \frac{2}{2 + 2} = 0.5$
  • Acurácia: $A = \frac{4 + 2}{4 + 1 + 2 + 2} \approx 0.667$
  • Precisão: $P = \frac{4}{4 + 2} \approx 0.667$

Podemos perceber que usando a análise binária, esse dataset e a predição não criteriosa não produziu resultados magníficos, mas ao mesmo tempo, por ser binário, teve números de probabilidade consideravelmente altos.


Testando em Python, com predição real

import pandas as pd
import numpy as np
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix

# Carregar o dataset
column_names = [
    'Class',
    'Alcohol',
    'Malic Acid',
    'Ash',
    'Alcalinity of Ash',
    'Magnesium',
    'Total Phenols',
    'Flavanoids',
    'Nonflavanoid Phenols',
    'Proanthocyanins',
    'Color Intensity',
    'Hue',
    'OD280/OD315 of Diluted Wines',
    'Proline'
]

# Carregar o arquivo de dados
data = pd.read_csv('wine.data', header=None, names=column_names)

# Selecionar apenas as colunas 'Alcohol' e 'Proline' para características
X = data[['Alcohol', 'Proline']]
y = data['Class']

# Dividir os dados em conjuntos de treinamento e teste
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.3, random_state=42)

# Criar e treinar o modelo de Regressão Logística
model = LogisticRegression(max_iter=1000, multi_class='auto', solver='lbfgs')
model.fit(X_train, y_train)

# Fazer previsões
predictions = model.predict(X_test)

# Calcular a acurácia
accuracy = accuracy_score(y_test, predictions)
print(f'Acurácia: {accuracy:.2f}')

# Matriz de confusão
print("\nMatriz de Confusão:")
print(confusion_matrix(y_test, predictions))

# Relatório de classificação
print("\nRelatório de Classificação:")
print(classification_report(y_test, predictions))

Foi utilizado algumas funções prontas de python para a realização deste teste. Pode-se notar que foi utilizado uma regressão logistica para prever os resultados do modelo. Na regressão logística, uma transformação logit é aplicada à chance, isto é, a probabilidade de sucesso dividida pela probabilidade de fracasso. .

Change de acontecer / chance de não acontecer quanto mais perto de 1 é que vai acontecer, mais perto de 0 é que não vai.

Avaliação

Neste caso aqui, foram utilizados as 3 colunas possíveis do dataset, dispostas nas linhas, ao lado do que foi predito, nas colunas.

Matriz de Confusão

Predito 1Predito 2Predito 3Total
Real 1190019
Real 2019221
Real 3131014
Total20221254

Métodos de avaliação

Os métodos de avaliação utilizados foram gerados automaticamente pelo código classification_report(y_test, predictions), baseado na coluna de “Classes” (Resultados Reais) e no que foi predito. Dos tipos de classificação gerados, vimos apenas o da precisão.

Acurácia: 0.89

ClassePrecisãoEspecificadadeF1-Score
10.951.000.97
20.860.900.88
30.830.710.77
Média0.880.870.88
Ponderada0.890.890.89