Ficha 01 · IA fundamentos + ML
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.