Sklearn 模型评估与调优
在 Scikit-learn(sklearn)中,模型评估和模型调优是机器学习工作流中的关键步骤,用于衡量模型性能并优化其参数以提高预测能力。以下是关于 sklearn 模型评估与调优的详细指南,涵盖核心概念、常用方法、代码示例和最佳实践,力求简洁清晰。
一、模型评估
模型评估用于量化模型在训练数据和测试数据上的表现,检测过拟合或欠拟合。Scikit-learn 提供了丰富的评估工具,位于 sklearn.metrics 和 sklearn.model_selection 模块。
1.1 评估指标
根据任务类型,sklearn 提供不同的评估指标:
分类任务
- 准确率(Accuracy):正确预测样本的比例。
from sklearn.metrics import accuracy_score
accuracy = accuracy_score(y_test, y_pred)
print(f"Accuracy: {accuracy:.3f}")
- 精确率、召回率、F1 分数:适合不平衡数据集。
from sklearn.metrics import classification_report
print(classification_report(y_test, y_pred, target_names=['class_0', 'class_1']))
输出示例:
precision recall f1-score support
class_0 0.95 0.90 0.92 20
class_1 0.91 0.95 0.93 21
accuracy 0.93 41
macro avg 0.93 0.93 0.93 41
- ROC-AUC:衡量分类器区分正负类的能力。
from sklearn.metrics import roc_auc_score
y_prob = model.predict_proba(X_test)[:, 1] # 概率值
auc = roc_auc_score(y_test, y_prob)
print(f"ROC-AUC: {auc:.3f}")
回归任务
- 均方误差(MSE):预测值与真实值的平均平方差。
from sklearn.metrics import mean_squared_error
mse = mean_squared_error(y_test, y_pred)
print(f"MSE: {mse:.3f}")
- 均绝对误差(MAE):预测值与真实值的平均绝对差。
from sklearn.metrics import mean_absolute_error
mae = mean_absolute_error(y_test, y_pred)
print(f"MAE: {mae:.3f}")
- R² 分数:解释模型对数据的拟合程度(0-1,1 为最佳)。
from sklearn.metrics import r2_score
r2 = r2_score(y_test, y_pred)
print(f"R²: {r2:.3f}")
聚类任务
- 轮廓系数(Silhouette Score):衡量簇内紧密度和簇间分离度(-1 到 1)。
from sklearn.metrics import silhouette_score
score = silhouette_score(X, clusters)
print(f"Silhouette Score: {score:.3f}")
- 调整兰德指数(ARI):比较聚类结果与真实标签的相似性。
from sklearn.metrics import adjusted_rand_score
ari = adjusted_rand_score(y_true, clusters)
print(f"ARI: {ari:.3f}")
1.2 交叉验证
交叉验证通过多次拆分数据评估模型的稳定性,防止测试集单一划分的偶然性。
- K 折交叉验证:
将数据分为 K 折,依次用 K-1 折训练,1 折验证。
from sklearn.model_selection import cross_val_score
from sklearn.linear_model import LogisticRegression
model = LogisticRegression(max_iter=200)
scores = cross_val_score(model, X, y, cv=5, scoring='accuracy')
print(f"Cross-Validation Accuracy: {scores.mean():.3f} ± {scores.std():.3f}")
- Stratified K-Fold:分类任务中保持类别分布。
from sklearn.model_selection import StratifiedKFold
skf = StratifiedKFold(n_splits=5)
scores = cross_val_score(model, X, y, cv=skf, scoring='accuracy')
print(f"Stratified CV Accuracy: {scores.mean():.3f}")
1.3 训练/测试拆分
使用 train_test_split 将数据分为训练集和测试集,评估泛化能力。
from sklearn.model_selection import train_test_split
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
二、模型调优
模型调优通过调整超参数优化性能。Scikit-learn 提供 GridSearchCV 和 RandomizedSearchCV 等工具,位于 sklearn.model_selection。
2.1 超参数调优方法
GridSearchCV
遍历所有参数组合,找到最佳参数。
from sklearn.model_selection import GridSearchCV
from sklearn.svm import SVC
param_grid = {
'C': [0.1, 1, 10],
'kernel': ['linear', 'rbf'],
'gamma': ['scale', 'auto']
}
model = SVC()
grid_search = GridSearchCV(model, param_grid, cv=5, scoring='accuracy')
grid_search.fit(X_train, y_train)
print("Best Parameters:", grid_search.best_params_)
print("Best CV Score:", grid_search.best_score_)
RandomizedSearchCV
随机采样参数组合,适合大规模搜索。
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import uniform
param_dist = {
'C': uniform(0.1, 10),
'kernel': ['linear', 'rbf'],
'gamma': ['scale', 'auto']
}
model = SVC()
random_search = RandomizedSearchCV(model, param_dist, n_iter=10, cv=5, random_state=42)
random_search.fit(X_train, y_train)
print("Best Parameters:", random_search.best_params_)
print("Best CV Score:", random_search.best_score_)
2.2 Pipeline 集成预处理与调优
Pipeline 结合预处理和模型,防止数据泄漏。
from sklearn.pipeline import Pipeline
from sklearn.preprocessing import StandardScaler
from sklearn.ensemble import RandomForestClassifier
pipeline = Pipeline([
('scaler', StandardScaler()),
('rf', RandomForestClassifier(random_state=42))
])
param_grid = {
'rf__n_estimators': [50, 100, 200],
'rf__max_depth': [None, 10, 20]
}
grid_search = GridSearchCV(pipeline, param_grid, cv=5)
grid_search.fit(X_train, y_train)
print("Best Parameters:", grid_search.best_params_)
三、完整示例(鸢尾花分类)
from sklearn.datasets import load_iris
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.preprocessing import StandardScaler
from sklearn.linear_model import LogisticRegression
from sklearn.metrics import accuracy_score, classification_report
from sklearn.pipeline import Pipeline
# 加载数据
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)
# 创建 Pipeline
pipeline = Pipeline([
('scaler', StandardScaler()),
('classifier', LogisticRegression(max_iter=200))
])
# 定义超参数网格
param_grid = {
'classifier__C': [0.1, 1, 10],
'classifier__penalty': ['l2']
}
# 网格搜索
grid_search = GridSearchCV(pipeline, param_grid, cv=5, scoring='accuracy')
grid_search.fit(X_train, y_train)
# 输出最佳参数和分数
print("Best Parameters:", grid_search.best_params_)
print("Best CV Score:", grid_search.best_score_)
# 测试集评估
y_pred = grid_search.predict(X_test)
print(f"Test Accuracy: {accuracy_score(y_test, y_pred):.3f}")
print("Classification Report:\n", classification_report(y_test, y_pred, target_names=iris.target_names))
输出示例:
Best Parameters: {'classifier__C': 1, 'classifier__penalty': 'l2'}
Best CV Score: 0.975
Test Accuracy: 1.000
Classification Report:
precision recall f1-score support
setosa 1.00 1.00 1.00 10
versicolor 1.00 1.00 1.00 9
virginica 1.00 1.00 1.00 11
accuracy 1.00 30
macro avg 1.00 1.00 1.00 30
四、注意事项
- 选择合适的评估指标:
- 不平衡数据避免只看准确率,优先 F1 或 AUC。
- 回归任务关注 MSE 或 R²,视业务需求而定。
- 防止数据泄漏:
- 预处理(如标准化)需在
fit_transform后对测试集仅用transform。 - 使用 Pipeline 确保流程一致。
- 交叉验证策略:
- 小数据集用 K 折(cv=5 或 10)。
- 大数据集用较少折(如 cv=3)以节省时间。
- 调优效率:
- GridSearchCV 适合小参数空间。
- RandomizedSearchCV 适合大参数空间或快速实验。
- 过拟合风险:
- 监控训练集和测试集的性能差距。
- 使用正则化(如 LogisticRegression 的
C或 RandomForest 的max_depth)。
五、资源
- 官方文档:
- 评估:https://scikit-learn.org/stable/modules/model_evaluation.html
- 调优:https://scikit-learn.org/stable/modules/grid_search.html
- 示例:https://scikit-learn.org/stable/auto_examples/model_selection/index.html
- 社区:在 X 平台搜索
#scikit-learn获取最新讨论。
如果需要 可视化评估结果(如 ROC 曲线、混淆矩阵)、特定模型的调优技巧,或针对某任务(如回归、不平衡分类)的完整代码,请告诉我,我可以提供详细示例!