Scikit-learn 1.0 机器学习:模型选择与调参

模型选择与调参是机器学习流程的核心环节,Scikit-learn 1.0 提供了系统化的工具实现这一过程。以下是关键步骤和方法:


1. 模型选择基础

在监督学习中,模型选择需平衡偏差与方差:

  • 偏差:模型预测值与真实值的系统性误差,对应欠拟合
  • 方差:模型对训练数据扰动的敏感性,对应过拟合
    最优模型需最小化泛化误差:
    $$ \text{泛化误差} = \text{偏差}^2 + \text{方差} + \text{噪声} $$

2. 交叉验证(Cross-Validation)

评估模型泛化能力的黄金标准:

  • k折交叉验证:将数据分为$k$个互斥子集
    $$ \text{最终得分} = \frac{1}{k} \sum_{i=1}^{k} \text{score}_i $$
  • Scikit-learn 实现:
    from sklearn.model_selection import cross_val_score
    scores = cross_val_score(estimator, X, y, cv=5)  # 5折交叉验证
    


3. 超参数调优方法

(1) 网格搜索(GridSearchCV)
穷举指定参数组合:

from sklearn.svm import SVC
from sklearn.model_selection import GridSearchCV

param_grid = {
    'C': [0.1, 1, 10],          # 正则化强度
    'kernel': ['linear', 'rbf'], # 核函数类型
    'gamma': [0.01, 0.1, 1]      # RBF核系数
}

grid_search = GridSearchCV(
    estimator=SVC(),
    param_grid=param_grid,
    cv=5,                        # 5折交叉验证
    scoring='accuracy'           # 评估指标
)
grid_search.fit(X_train, y_train)
print(f"最优参数: {grid_search.best_params_}")

(2) 随机搜索(RandomizedSearchCV)
高效探索高维参数空间:

from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import loguniform

param_dist = {
    'C': loguniform(1e-3, 1e3),  # 对数均匀分布采样
    'gamma': loguniform(1e-4, 1e1)
}

random_search = RandomizedSearchCV(
    SVC(), 
    param_dist, 
    n_iter=50,                   # 随机采样次数
    cv=5
)
random_search.fit(X_train, y_train)


4. 高级调优技术
  • 贝叶斯优化:使用scikit-optimize
    from skopt import BayesSearchCV
    bayes_search = BayesSearchCV(SVC(), search_spaces, n_iter=30, cv=5)
    

  • 集成方法:通过VotingClassifierStackingCVClassifier组合多个模型

5. 模型评估与选择
  • 关键指标
    • 分类:准确率、F1值、ROC-AUC
    • 回归:$R^2$、MSE
  • 学习曲线分析
    from sklearn.model_selection import learning_curve
    train_sizes, train_scores, val_scores = learning_curve(
        estimator, X, y, cv=5, scoring='accuracy'
    )
    


6. 最佳实践
  1. 使用train_test_split分离初始训练集和测试集
  2. 在训练集上执行交叉验证调参
  3. 最终在测试集上评估模型性能
  4. 对于小数据集,使用分层抽样(StratifiedKFold

示例完整流程:

# 数据准备
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2)

# 参数调优
grid_search = GridSearchCV(SVC(), param_grid, cv=5)
grid_search.fit(X_train, y_train)

# 最终评估
best_model = grid_search.best_estimator_
y_pred = best_model.predict(X_test)
print(classification_report(y_test, y_pred))

更多推荐