KNN
precision recall f1-score support 0 0.783 0.837 0.809 43 1 0.562 0.474 0.514 19 accuracy 0.726 62 macro avg 0.673 0.655 0.662 62 weighted avg 0.715 0.726 0.719 62
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from io import StringIO
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler
from sklearn.neighbors import KNeighborsClassifier
from sklearn.metrics import accuracy_score, classification_report, confusion_matrix
from sklearn.decomposition import PCA
# ===== 1) Carrega o CSV =====
df = pd.read_csv('https://raw.githubusercontent.com/marcelademartini/Machine-Learning-1/refs/heads/main/Testing.csv')
# Define a coluna alvo
target = 'Outcome' if 'Outcome' in df.columns else df.columns[-1]
# X e y (dummies para categóricas)
X_raw = df.drop(columns=[target])
X = pd.get_dummies(X_raw, drop_first=True)
y = df[target]
# Codifica alvo não numérico
if not np.issubdtype(y.dtype, np.number):
y = pd.factorize(y)[0]
# Trata NaN
X = X.fillna(X.median(numeric_only=True))
# ===== 2) Split + escala =====
X_train, X_test, y_train, y_test = train_test_split(
X, y, test_size=0.2, random_state=42, stratify=y if len(np.unique(y)) > 1 else None
)
scaler = StandardScaler()
X_train_s = scaler.fit_transform(X_train)
X_test_s = scaler.transform(X_test)
# ===== 3) Treina KNN =====
k = 3
knn = KNeighborsClassifier(n_neighbors=k)
knn.fit(X_train_s, y_train)
y_pred = knn.predict(X_test_s)
# ===== 4) Métricas =====
acc = accuracy_score(y_test, y_pred)
print(classification_report(y_test, y_pred, digits=3))
# ===== Helper: imprimir figura como SVG =====
def print_svg_current_fig():
buf = StringIO()
plt.savefig(buf, format="svg", transparent=True, bbox_inches="tight")
print(buf.getvalue())
plt.close()
# ===== 5) Matriz de confusão =====
cm = confusion_matrix(y_test, y_pred)
plt.figure(figsize=(5,4), dpi=120)
plt.imshow(cm, interpolation='nearest')
plt.title("Matriz de Confusão (teste)")
plt.xlabel("Predito")
plt.ylabel("Real")
for i in range(cm.shape[0]):
for j in range(cm.shape[1]):
plt.text(j, i, str(cm[i, j]), ha="center", va="center")
plt.colorbar()
print_svg_current_fig()
# ===== 6) Visualização 2D (PCA) da fronteira de decisão =====
if X_train.shape[1] >= 2:
pca = PCA(n_components=2, random_state=42)
X_train_2d = pca.fit_transform(X_train_s)
X_test_2d = pca.transform(X_test_s)
knn_viz = KNeighborsClassifier(n_neighbors=k).fit(X_train_2d, y_train)
h = 0.05
x_min, x_max = X_train_2d[:, 0].min() - 0.5, X_train_2d[:, 0].max() + 0.5
y_min, y_max = X_train_2d[:, 1].min() - 0.5, X_train_2d[:, 1].max() + 0.5
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))
Z = knn_viz.predict(np.c_[xx.ravel(), yy.ravel()]).reshape(xx.shape)
plt.figure(figsize=(6,5), dpi=120)
plt.contourf(xx, yy, Z, alpha=0.30)
plt.scatter(X_train_2d[:,0], X_train_2d[:,1], c=y_train, s=20, marker='o', label='treino')
plt.scatter(X_test_2d[:,0], X_test_2d[:,1], c=y_test, s=40, marker='x', label='teste')
plt.title(f"Fronteira de Decisão (PCA 2D) — KNN k={k}")
plt.xlabel("PC1")
plt.ylabel("PC2")
plt.legend(loc="best")
print_svg_current_fig()
1) Exploração dos Dados
-
Leitura do conjunto de dados: o CSV é carregado de uma URL do GitHub para o DataFrame df:
-
df = pd.read_csv('https://raw.githubusercontent.com/.../Testing.csv').
-
Natureza do problema (supervisionado): o código define automaticamente a coluna-alvo para classificação:
-
target = 'Outcome' se essa coluna existir; caso contrário, usa a última coluna do CSV (df.columns[-1]).
-
Separação inicial de variáveis:
-
X_raw = df.drop(columns=[target]) (preditoras).
-
y = df[target] (alvo).
-
Tipos de dados:
-
Preditoras categóricas são transformadas em dummies com pd.get_dummies(..., drop_first=True), o que cria colunas binárias para categorias.
-
Se o alvo não for numérico, ele é codificado em inteiros com pd.factorize.
2) Pré-processamento
- Tratamento de ausentes (NaN):
X = X.fillna(X.median(numeric_only=True)): preenche valores faltantes nas colunas numéricas com a mediana de cada coluna.
- Codificação de categóricas:
pd.get_dummies(X_raw, drop_first=True): converte todas as colunas categóricas de X_raw para variáveis indicadoras, descartando a primeira categoria (evita redundância).
-
Padronização (normalização z-score):
-
StandardScaler() é ajustado em X_train e aplicado em X_train/X_test, produzindo X_train_s e X_test_s. Isso centraliza (média 0) e escala (desvio 1) as features, o que é importante para KNN.
3) Divisão dos Dados
-
Hold-out 80/20:
-
train_test_split(..., test_size=0.2, random_state=42, stratify=...).
-
Estratificação:
-
Se houver mais de uma classe no alvo, o split é estratificado para manter as proporções de classes em treino e teste.
-
Reprodutibilidade:
-
random_state=42 garante que a mesma divisão seja reproduzível.
4) Treinamento do Modelo (KNN)
-
Algoritmo: KNeighborsClassifier com n_neighbors=k, onde k = 3.
-
Treinamento:
-
knn.fit(X_train_s, y_train) usa as features padronizadas de treino.
-
Predição:
-
y_pred = knn.predict(X_test_s) gera as classes previstas para o conjunto de teste.
5) Avaliação do Modelo
-
Métricas impressas:
-
accuracy_score(y_test, y_pred) (acurácia) é calculada e armazenada em acc.
-
classification_report(y_test, y_pred, digits=3) é impresso no console com precision, recall, f1-score e support por classe, além das médias.
-
Matriz de confusão (figura):
-
confusion_matrix(y_test, y_pred) gera a matriz cm.
-
Em seguida, é plotada com plt.imshow(cm, ...), adiciona-se plt.colorbar() e os números das células são sobrepostos com plt.text(...).
-
A figura é exportada como SVG por print_svg_current_fig(), que salva no buffer (StringIO) e imprime o SVG no stdout (útil para ambientes que capturam a saída).
Visualização da fronteira de decisão em 2D (PCA):
-
Se X_train tiver ≥ 2 features, aplica-se PCA para reduzir X_train_s/X_test_s a 2 componentes: X_train_2d, X_test_2d.
-
Treina-se um KNN separado para visualização (knn_viz) neste espaço 2D.
-
Cria-se uma malha (np.meshgrid) e plota-se plt.contourf(...) com as regiões de decisão do KNN em 2D.
-
Os pontos de treino (círculos) e teste (xis) são sobrepostos, coloridos pelas classes verdadeiras.
-
Esta figura também é exportada como SVG via print_svg_current_fig().
6) Relatório Final (documentação do que o código produz)
-
Processo documentado pelo código:
-
Entrada: leitura do CSV remoto e definição automática do alvo.
-
Pré-processamento: dummies para categóricas, fatorização do alvo se necessário, imputação por mediana para NaN e padronização via StandardScaler.
-
Divisão: treino/teste 80/20 com estratificação quando aplicável.
-
Modelo: KNN com k=3, treinado em dados padronizados.
-
Saídas:
-
Texto: relatório de classificação (precision, recall, f1, support) e a acurácia (em acc).
-
Figuras (SVG, impressas no stdout):
-
Matriz de confusão do conjunto de teste.
-
Fronteira de decisão em 2D após redução por PCA, com pontos de treino e teste.
-
Resultados obtidos:
-
O console exibirá o classification_report com métricas por classe e médias; a acurácia está disponível na variável acc.
-
Duas figuras SVG são geradas na saída: (i) Matriz de confusão e (ii) Fronteira de decisão (PCA 2D).
*Possíveis melhorias (nota descritiva): não fazem parte do código atual; portanto, o relatório final se limita às etapas e produtos acima executados pelo script.