Sklearn 模型评估与调优(超详细)

为什么模型评估与调优是机器学习的关键环节

在机器学习项目中,模型训练只是第一步。就像体检报告不能只看身高体重一样,我们也不能仅凭训练集准确率判断模型好坏。Sklearn 模型评估与调优是确保模型具备实用价值的核心步骤,它帮助我们回答两个关键问题:模型表现是否可靠?还有没有提升空间?

模型评估的四把尺子

理解基本指标体系

在 Sklearn 中,模型评估通常围绕四个核心指标展开:准确率(Accuracy)、精确率(Precision)、召回率(Recall)和 F1 分数。这些指标如同体检报告的不同项目,各自反映模型的不同健康状况。

from sklearn.metrics import accuracy_score, precision_score, recall_score, f1_score
import numpy as np

y_true = np.array([0, 1, 1, 0, 1])  # 真实标签
y_pred = np.array([0, 1, 0, 0, 1])  # 预测结果

accuracy = accuracy_score(y_true, y_pred)  # 总体正确率
precision = precision_score(y_true, y_pred)  # 预测为正的样本中有多少真实为正
recall = recall_score(y_true, y_pred)  # 真实为正的样本中有多少被正确预测
f1 = f1_score(y_true, y_pred)  # 精确率和召回率的调和平均

print(f"准确率: {accuracy:.2f}")
print(f"精确率: {precision:.2f}")
print(f"召回率: {recall:.2f}")
print(f"F1分数: {f1:.2f}")

分类问题的特殊考量

在处理不平衡数据集时,准确率会像"好学生偏科"般产生误导。例如医疗诊断场景中,99%的健康样本会让我们误以为 99%的准确率已足够优秀。这时就需要用混淆矩阵(Confusion Matrix)这种"详细成绩单"来分析。

from sklearn.metrics import confusion_matrix
import pandas as pd

cm = confusion_matrix(y_true, y_pred)
pd_cm = pd.DataFrame(cm, index=['实际健康', '实际患病'], columns=['预测健康', '预测患病'])
print(pd_cm)

交叉验证:给模型做压力测试

K折交叉验证原理

就像给汽车做多角度安全测试,交叉验证通过多次划分数据集来检验模型的稳定性。Scikit-learn 提供的 KFold 类可以让我们轻松实现这个过程。

from sklearn.model_selection import KFold
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification

X, y = make_classification(n_samples=100, n_features=4, random_state=42)

kf = KFold(n_splits=5, shuffle=True, random_state=42)

for train_index, test_index in kf.split(X):
    X_train, X_test = X[train_index], X[test_index]
    y_train, y_test = y[train_index], y[test_index]
    
    model = RandomForestClassifier()
    model.fit(X_train, y_train)
    score = model.score(X_test, y_test)
    print(f"本轮准确率: {score:.2f}")

交叉验证的高级用法

在 Sklearn 1.0.2 版本中,交叉验证可以和评估指标结合使用。通过指定 scoring 参数,我们可以获得更全面的模型表现数据。

from sklearn.model_selection import cross_val_score

scores = cross_val_score(RandomForestClassifier(), X, y, cv=5, scoring='f1')
print(f"F1分数均值: {scores.mean():.2f} ± {scores.std():.2f}")

网格搜索:自动寻找最佳参数组合

参数调优的黄金工具

想象自己是调酒师,我们需要找到最佳配方。GridSearchCV 就是这个过程的自动化工具,它会系统性地尝试所有参数组合。

from sklearn.model_selection import GridSearchCV

param_grid = {
    'n_estimators': [10, 50, 100],
    'max_depth': [3, 5, 7]
}

grid_search = GridSearchCV(RandomForestClassifier(), param_grid, cv=5, scoring='f1')
grid_search.fit(X, y)

print(f"最佳参数组合: {grid_search.best_params_}")
print(f"最佳F1分数: {grid_search.best_score_:.2f}")

理解搜索结果

网格搜索结束后,我们可以通过 cv_results_ 属性查看所有参数组合的评估结果。这就像得到一份完整的实验记录,帮助我们理解不同参数对模型的影响。

results_df = pd.DataFrame(grid_search.cv_results_)
print(results_df[['params', 'mean_test_score', 'std_test_score']])

学习曲线:诊断模型性能瓶颈

绘制学习曲线

学习曲线能告诉我们模型是"吃不饱"还是"吃撑了"。通过观察准确率随样本数量变化的趋势,我们可以判断是否需要增加数据或调整模型复杂度。

import matplotlib.pyplot as plt
from sklearn.model_selection import learning_curve

train_sizes, train_scores, test_scores = learning_curve(
    RandomForestClassifier(), X, y, cv=5
)

train_scores_mean = np.mean(train_scores, axis=1)
test_scores_mean = np.mean(test_scores, axis=1)

plt.plot(train_sizes, train_scores_mean, label='训练集准确率')
plt.plot(train_sizes, test_scores_mean, label='验证集准确率')
plt.legend()
plt.xlabel('训练样本数量')
plt.ylabel('准确率')
plt.show()

解读学习曲线

当训练集和验证集准确率同时上升且趋于平稳,说明模型"学习效果良好"。如果两者差距较大,可能需要增加正则化参数。这种分析方法在 Sklearn 模型评估与调优中特别实用。

实战案例:糖尿病预测模型优化

数据准备与预处理

使用 Sklearn 自带的糖尿病数据集进行演示,这个案例将完整展示模型评估与调优的流程。

from sklearn.datasets import load_diabetes
from sklearn.model_selection import train_test_split
from sklearn.preprocessing import StandardScaler

diabetes = load_diabetes()
X, y = diabetes.data, diabetes.target

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

scaler = StandardScaler()
X_train = scaler.fit_transform(X_train)
X_test = scaler.transform(X_test)

构建基准模型

先建立一个未经优化的模型作为参考基准,就像考试前先做一次模拟测试。

from sklearn.linear_model import Ridge

base_model = Ridge()
base_model.fit(X_train, y_train)

train_score = base_model.score(X_train, y_train)
test_score = base_model.score(X_test, y_test)
print(f"训练集R²: {train_score:.2f}")
print(f"测试集R²: {test_score:.2f}")

进行参数调优

使用网格搜索和交叉验证相结合的方式寻找最优参数。

from sklearn.svm import SVR

param_grid = {
    'C': [0.1, 1, 10],
    'kernel': ['linear', 'rbf']
}

grid_search = GridSearchCV(SVR(), param_grid, cv=5, scoring='r2')
grid_search.fit(X_train, y_train)

best_model = grid_search.best_estimator_
final_score = best_model.score(X_test, y_test)
print(f"优化后测试集R²: {final_score:.2f}")

验证调优效果

通过对比调优前后的模型表现,可以直观感受到 Sklearn 模型评估与调优带来的提升。

训练集R²: 0.35
测试集R²: 0.29
优化后测试集R²: 0.33

常用调优技巧总结

  1. 参数优先级策略:先调整影响最大的参数(如决策树的 max_depth)
  2. 特征工程配合:调优时要结合特征选择(SelectKBest)和特征缩放(StandardScaler)
  3. 迭代式优化:先用粗粒度搜索范围,再逐步缩小搜索区间
  4. 早停机制:对迭代模型(如梯度提升)使用 early_stopping 参数

参数调优对比表

参数类型 常见范围 调优建议
正则化系数 0.01-100 对数尺度搜索效果更佳
树深度 3-15 与样本量成正比调整
学习率 0.001-0.2 通常从 0.1 开始尝试
随机森林数量 50-500 需要平衡计算资源和性能提升

结语:持续优化的机器学习之路

通过本文的讲解,相信读者已经掌握了 Sklearn 模型评估与调优的核心方法。记住,优秀的模型不是一蹴而就的,而是通过不断验证、调整参数、优化特征逐步成型。建议读者在实际项目中结合业务场景,灵活运用这些方法。毕竟,机器学习就像调酒,既需要科学的方法论,也需要一点艺术的直觉。