Sklearn 模型评估与调优

在 Scikit-learn(sklearn)中,模型评估模型调优是机器学习工作流中的关键步骤,用于衡量模型性能并优化其参数以提高预测能力。以下是关于 sklearn 模型评估与调优的详细指南,涵盖核心概念、常用方法、代码示例和最佳实践,力求简洁清晰。


一、模型评估

模型评估用于量化模型在训练数据和测试数据上的表现,检测过拟合或欠拟合。Scikit-learn 提供了丰富的评估工具,位于 sklearn.metricssklearn.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 提供 GridSearchCVRandomizedSearchCV 等工具,位于 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

四、注意事项

  1. 选择合适的评估指标
  • 不平衡数据避免只看准确率,优先 F1 或 AUC。
  • 回归任务关注 MSE 或 R²,视业务需求而定。
  1. 防止数据泄漏
  • 预处理(如标准化)需在 fit_transform 后对测试集仅用 transform
  • 使用 Pipeline 确保流程一致。
  1. 交叉验证策略
  • 小数据集用 K 折(cv=5 或 10)。
  • 大数据集用较少折(如 cv=3)以节省时间。
  1. 调优效率
  • GridSearchCV 适合小参数空间。
  • RandomizedSearchCV 适合大参数空间或快速实验。
  1. 过拟合风险
  • 监控训练集和测试集的性能差距。
  • 使用正则化(如 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 曲线、混淆矩阵)特定模型的调优技巧,或针对某任务(如回归、不平衡分类)的完整代码,请告诉我,我可以提供详细示例!

类似文章

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注