Partilhar: WhatsApp
aulify
UC UC00623 · T. Desenv. Software, T. Multimédia

Ficha 01 · IA fundamentos + ML

scikit-learn, classificação, métricas
Versão · Aluno
Tempo · 45 minutos
Aluno(a)
Turma
Data

Exercício 1 · Setup scikit-learn

Instala scikit-learn e pandas. Carrega o dataset Iris (incluído no sklearn) e mostra: shape, primeiras 5 linhas, nomes das classes.

Resposta:
pip install scikit-learn pandas matplotlib seaborn
from sklearn.datasets import load_iris
import pandas as pd

iris = load_iris(as_frame=True)
df = iris.frame

print("Shape:", df.shape)
# (150, 5) — 150 amostras, 4 features + 1 target

print(df.head())
#    sepal length (cm)  sepal width  petal length  petal width  target
# 0  5.1                3.5          1.4           0.2          0
# ...

print("Classes:", iris.target_names)
# ['setosa' 'versicolor' 'virginica']

Exercício 2 · Train/test split

Divide o Iris em 80/20 train/test. Treina um KNN classifier. Imprime a accuracy no test set.

Resposta:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier

iris = load_iris()
X, y = iris.data, iris.target

X_train, X_test, y_train, y_test = train_test_split(
    X, y, test_size=0.2, random_state=42, stratify=y
)

model = KNeighborsClassifier(n_neighbors=5)
model.fit(X_train, y_train)
acc = model.score(X_test, y_test)
print(f"Accuracy: {acc:.2%}")
# Esperado: ~97%

stratify=y garante mesma proporção de classes em train e test.

Exercício 3 · Comparar modelos

Treina 3 modelos diferentes (KNN, Decision Tree, Logistic Regression) no Iris. Imprime a accuracy de cada um numa tabela.

Resposta:
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split
from sklearn.neighbors import KNeighborsClassifier
from sklearn.tree import DecisionTreeClassifier
from sklearn.linear_model import LogisticRegression

iris = load_iris()
X_train, X_test, y_train, y_test = train_test_split(
    iris.data, iris.target, test_size=0.2, random_state=42, stratify=iris.target
)

modelos = {
    "KNN": KNeighborsClassifier(n_neighbors=5),
    "Decision Tree": DecisionTreeClassifier(random_state=42),
    "Logistic Reg": LogisticRegression(max_iter=200),
}

print(f"{'Modelo':<15} {'Accuracy':>10}")
print("-" * 28)
for nome, m in modelos.items():
    m.fit(X_train, y_train)
    acc = m.score(X_test, y_test)
    print(f"{nome:<15} {acc:>9.2%}")

Exercício 4 · Métricas — classification_report

Para o melhor modelo do exercício 3, imprime o classification_report (precision, recall, f1 por classe).

Resposta:
from sklearn.metrics import classification_report, confusion_matrix
from sklearn.tree import DecisionTreeClassifier

model = DecisionTreeClassifier(random_state=42)
model.fit(X_train, y_train)
preds = model.predict(X_test)

print("Classification Report:")
print(classification_report(y_test, preds, target_names=iris.target_names))

print("\nConfusion Matrix:")
print(confusion_matrix(y_test, preds))

Output típico:

              precision    recall  f1-score   support
      setosa       1.00      1.00      1.00        10
  versicolor       1.00      1.00      1.00        10
   virginica       1.00      1.00      1.00        10
    accuracy                           1.00        30

Exercício 5 · Regressão linear

Usa o dataset load_diabetes do sklearn. Treina uma regressão linear para prever a progressão da doença. Imprime R² no test set.

Resposta:
from sklearn.datasets import load_diabetes
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import r2_score, mean_squared_error
import numpy as np

X, y = load_diabetes(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

model = LinearRegression()
model.fit(X_train, y_train)
preds = model.predict(X_test)

r2 = r2_score(y_test, preds)
rmse = np.sqrt(mean_squared_error(y_test, preds))

print(f"R²: {r2:.3f}")    # ~0.45
print(f"RMSE: {rmse:.1f}") # erro médio em unidades de y

R² baixo indica que features lineares não chegam — pode-se experimentar Random Forest ou XGBoost.

Exercício 6 · Classificador de texto (TF-IDF + Naive Bayes)

Cria um classificador de spam usando estes dados de exemplo:

emails = [
    "Win a free iPhone now!", "Cheap meds, click here", "Earn $5000 weekly from home",
    "Meeting tomorrow at 3pm", "Project deadline next Friday", "Lunch later?",
    "FREE bitcoin opportunity", "Re: invoice attached", "Confirm your subscription",
    "Sale 50% off all items click", "Status update on the report", "Happy birthday!"
]
labels = [1,1,1, 0,0,0, 1,0,0, 1,0,0]  # 1=spam, 0=ham

Treina, prevê uma nova mensagem e imprime previsão.

Resposta:
from sklearn.feature_extraction.text import TfidfVectorizer
from sklearn.naive_bayes import MultinomialNB
from sklearn.pipeline import Pipeline

pipeline = Pipeline([
    ("tfidf", TfidfVectorizer(stop_words="english")),
    ("clf", MultinomialNB()),
])

pipeline.fit(emails, labels)

testes = [
    "Important meeting at 4pm",
    "WIN FREE iphone NOW limited offer",
    "Reminder: dentist appointment tomorrow",
]

for t in testes:
    pred = pipeline.predict([t])[0]
    proba = pipeline.predict_proba([t])[0]
    label = "SPAM" if pred == 1 else "HAM"
    print(f"{label} ({max(proba):.0%}) — {t}")

Com pouco dado (12 emails) o modelo é primitivo, mas demonstra o conceito. Em produção usar dataset SMS Spam Collection (5.5k samples).

Exercício 7 · Pipeline + GridSearchCV

Usa GridSearchCV para encontrar o melhor n_neighbors (1 a 20) para KNN no Iris, com 5-fold cross-validation.

Resposta:
from sklearn.datasets import load_iris
from sklearn.neighbors import KNeighborsClassifier
from sklearn.model_selection import GridSearchCV, train_test_split

X, y = load_iris(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

params = {"n_neighbors": list(range(1, 21))}

grid = GridSearchCV(
    KNeighborsClassifier(),
    param_grid=params,
    cv=5,
    scoring="accuracy",
)

grid.fit(X_train, y_train)

print(f"Melhor K: {grid.best_params_}")
print(f"CV score: {grid.best_score_:.3f}")
print(f"Test score: {grid.score(X_test, y_test):.3f}")

GridSearchCV tenta todas as combinações; para spaces grandes usa RandomizedSearchCV.

Exercício 8 · Visualização

Para o classificador KNN do exercício 2, faz scatter plot 2D usando apenas 2 features (sepal length vs petal length), colorindo por classe. Marca o decision boundary.

Resposta:
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import load_iris
from sklearn.neighbors import KNeighborsClassifier

iris = load_iris()
X = iris.data[:, [0, 2]]   # sepal length + petal length
y = iris.target

model = KNeighborsClassifier(n_neighbors=5)
model.fit(X, y)

# Grid de pontos
h = 0.05
x_min, x_max = X[:, 0].min() - 0.5, X[:, 0].max() + 0.5
y_min, y_max = X[:, 1].min() - 0.5, X[:, 1].max() + 0.5
xx, yy = np.meshgrid(np.arange(x_min, x_max, h), np.arange(y_min, y_max, h))

Z = model.predict(np.c_[xx.ravel(), yy.ravel()])
Z = Z.reshape(xx.shape)

plt.figure(figsize=(8, 6))
plt.contourf(xx, yy, Z, alpha=0.3, cmap="viridis")
plt.scatter(X[:, 0], X[:, 1], c=y, edgecolors="black", cmap="viridis")
plt.xlabel("Sepal length")
plt.ylabel("Petal length")
plt.title("KNN decision boundary (Iris)")
plt.savefig("knn_iris.png", dpi=150)
plt.show()

Visualização ajuda a perceber como o modelo "vê" o espaço.