Giao diện
Thực hành: Model Selection
🎯 Mục tiêu
🎯 Sau bài thực hành này, bạn sẽ:
- Áp dụng baseline-first approach trong thực tế
- So sánh multiple models một cách có hệ thống
- Sử dụng cross-validation đúng cách để đánh giá
Mô tả bài tập
Bạn cần xây dựng model phân loại email spam. Thay vì nhảy thẳng vào deep learning, bạn sẽ theo phương pháp baseline-first: bắt đầu đơn giản rồi tăng dần complexity.
Yêu cầu
Bài 1: Baseline Model
Tạo baseline đơn giản nhất có thể, sau đó xây dựng model logistic regression.
python
from sklearn.model_selection import cross_val_score, StratifiedKFold
from sklearn.linear_model import LogisticRegression
from sklearn.dummy import DummyClassifier
from sklearn.datasets import make_classification
import numpy as np
X, y = make_classification(
n_samples=1000, n_features=20,
n_informative=10, n_classes=2,
random_state=42, weights=[0.7, 0.3]
)
def build_baselines(X, y):
"""Tạo dummy baseline và logistic regression baseline.
Return dict với tên model và mean CV score."""
# TODO: Implement
passBài 2: Systematic Model Comparison
So sánh nhiều models với cùng cross-validation strategy.
python
from sklearn.ensemble import RandomForestClassifier, GradientBoostingClassifier
from sklearn.svm import SVC
from sklearn.neighbors import KNeighborsClassifier
import pandas as pd
def compare_models(X, y):
"""So sánh ít nhất 4 models, trả về DataFrame với
columns: model, mean_score, std_score, fit_time."""
# TODO: Implement
passBài 3: Bias-Variance Analysis
Phân tích overfitting vs underfitting qua learning curves.
python
from sklearn.model_selection import learning_curve
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
def plot_learning_curves(model, X, y, title="Learning Curve"):
"""Vẽ learning curve để phân tích bias-variance tradeoff."""
# TODO: Implement with sklearn learning_curve
passGợi ý
💡 Xem gợi ý
- Bài 1:
DummyClassifier(strategy='most_frequent')là baseline tối thiểu. Mọi model thực tế phải beat được nó. - Bài 2: Dùng
StratifiedKFold(n_splits=5)để đảm bảo mỗi fold giữ tỷ lệ class. Dùngcross_validatethaycross_val_scoređể lấy cả fit_time. - Bài 3: Learning curve cho thấy: train/val score hội tụ thấp → high bias, khoảng cách lớn → high variance.
Lời giải
✅ Xem lời giải
python
# Bài 1
from sklearn.model_selection import cross_validate
def build_baselines(X, y):
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
results = {}
models = {
'dummy_most_frequent': DummyClassifier(strategy='most_frequent'),
'logistic_regression': LogisticRegression(max_iter=1000, random_state=42),
}
for name, model in models.items():
scores = cross_val_score(model, X, y, cv=cv, scoring='f1')
results[name] = {'mean': scores.mean(), 'std': scores.std()}
return results
# Bài 2
def compare_models(X, y):
cv = StratifiedKFold(n_splits=5, shuffle=True, random_state=42)
models = {
'Logistic Regression': LogisticRegression(max_iter=1000),
'Random Forest': RandomForestClassifier(n_estimators=100, random_state=42),
'Gradient Boosting': GradientBoostingClassifier(random_state=42),
'KNN': KNeighborsClassifier(),
}
rows = []
for name, model in models.items():
result = cross_validate(model, X, y, cv=cv,
scoring='f1', return_train_score=True)
rows.append({
'model': name,
'mean_score': result['test_score'].mean(),
'std_score': result['test_score'].std(),
'fit_time': result['fit_time'].mean(),
})
return pd.DataFrame(rows).sort_values('mean_score', ascending=False)
# Bài 3
def plot_learning_curves(model, X, y, title="Learning Curve"):
train_sizes, train_scores, val_scores = learning_curve(
model, X, y, cv=5, n_jobs=-1,
train_sizes=np.linspace(0.1, 1.0, 10),
scoring='f1'
)
plt.figure(figsize=(10, 6))
plt.plot(train_sizes, train_scores.mean(axis=1), label='Train')
plt.plot(train_sizes, val_scores.mean(axis=1), label='Validation')
plt.fill_between(train_sizes,
train_scores.mean(axis=1) - train_scores.std(axis=1),
train_scores.mean(axis=1) + train_scores.std(axis=1), alpha=0.1)
plt.fill_between(train_sizes,
val_scores.mean(axis=1) - val_scores.std(axis=1),
val_scores.mean(axis=1) + val_scores.std(axis=1), alpha=0.1)
plt.xlabel('Training Set Size')
plt.ylabel('F1 Score')
plt.title(title)
plt.legend()
plt.grid(True)
plt.savefig('learning_curve.png', dpi=100, bbox_inches='tight')
plt.close()