
文章目录
课前导读
欢迎来到第29课!在之前的算法课程中,你接触了很多超参数:决策树的max_depth、随机森林的n_estimators、SVM的C和gamma……这些参数不同取值会极大影响模型性能。很多人调参靠“手感”——试着改一下,看分数变化,再试下一个。这种方法不仅耗时,而且容易陷入局部最优。
本课将教你系统化、自动化的超参数调优方法。核心思想很简单:定义参数候选范围,用交叉验证评估每个组合,然后选出最佳。网格搜索暴力穷举所有组合,适合参数少的情况;随机搜索随机采样,效率更高,尤其适合高维参数空间。此外,你还将学习如何用对数尺度搜索学习率等跨度大的参数,以及如何利用早停策略加速搜索。学完本课,你将告别“炼丹式”调参,用科学的方法找到最佳模型。
学习目标
完成本课学习后,你将能够:
- 解释 交叉验证在超参数调优中的作用:防止信息泄露,提供稳定的性能估计
- 使用
GridSearchCV进行网格搜索,理解参数网格的定义方式 - 使用
RandomizedSearchCV进行随机搜索,掌握参数分布(distributions)的设置 - 理解 对数均匀分布(
loguniform)在宽范围参数(如学习率)中的应用 - 使用
HalvingGridSearchCV/HalvingRandomSearchCV(连续减半搜索)加速调参 - 分析 调参结果:
cv_results_属性,绘制参数与分数的关系图 - 避免 常见的调参陷阱:测试集泄露、数据划分不当、过拟合验证集
- 应用 嵌套交叉验证评估最终模型的泛化性能
知识点理论讲解
一、超参数与模型参数的区别
- 模型参数:在训练过程中从数据中学习得到的,如线性回归的系数
coef_。 - 超参数:在训练前需要人为设定的,如决策树的深度、SVM的
C、随机森林的树数量。超参数的取值直接影响模型的结构和复杂度。
调参的目标:找到一组超参数,使得模型在未见过的数据上表现最佳。
二、交叉验证在调参中的作用
如果我们在同一测试集上反复调参、选择最佳模型,则测试集会逐渐被“污染”,最终评估的泛化性能会被高估。因此,调参时不能触碰测试集,而是用交叉验证来评估每一组超参数的稳定性。
标准流程:
- 将原始数据划分为训练集 + 测试集(测试集仅用于最终评估)。
- 在训练集上进行交叉验证(如5折),每组超参数得到平均验证分数。
- 选择交叉验证分数最高的超参数组合。
- 用该组合在整个训练集上重新训练模型,最后在测试集上评估一次。
交叉验证确保调参过程不依赖于某一次特定的数据划分。
三、网格搜索(GridSearchCV)
原理:穷举给定的参数候选值列表,对所有组合进行交叉验证,选择得分最高的一组。
优点:保证在候选空间中找到最优组合(若候选空间包含全局最优)。
缺点:当参数较多、候选值较多时,计算量爆炸(维度灾难)。例如,3个参数,每个有10个候选,需要训练 10^3 = 1000 次模型,每次还要 K 折交叉验证(如5折),总训练次数 = 参数组合数 × K。
适用:参数空间小(≤4维),候选值少。
四、随机搜索(RandomizedSearchCV)
原理:在参数空间中按指定分布随机采样一定数量的组合(n_iter),对每个组合进行交叉验证。
优点:
- 效率远高于网格搜索,尤其当大部分参数对性能影响不大时,随机搜索可以更快找到较好的区域。
- 支持参数分布(如对数均匀分布),可以更智能地搜索宽范围参数。
缺点:不保证找到全局最优(但通常能找到足够好的解)。
适用:参数空间较大,或有一些参数具有宽范围(如学习率 1e-5 到 1)。
五、连续减半搜索(HalvingGridSearchCV / HalvingRandomSearchCV)
原理:一种迭代式搜索策略,初始用大量参数组合,但只用少量资源(如少量样本或少量迭代)评估,保留表现最好的一半,下一轮加倍资源,直到达到全部资源。
优点:比随机搜索更高效,能更早淘汰差参数。
缺点:实现复杂,可能因过早淘汰而错失后期表现好的参数。
六、参数空间的构建
定义参数候选的方式:
- 列表:
{'C': [0.1, 1, 10], 'gamma': [0.01, 0.1, 1]} - 范围(随机搜索):
scipy.stats.uniform(loc, scale):均匀分布scipy.stats.loguniform(a, b):对数均匀分布(适合学习率等跨度大的参数)scipy.stats.randint(a, b):整数均匀分布
七、结果分析与最佳模型
搜索完成后,可以从 cv_results_ 属性中提取详细信息:
mean_test_score:每组参数的平均交叉验证分数std_test_score:标准差(反映稳定性)params:参数组合rank_test_score:排名
最佳模型可通过 best_estimator_、best_params_、best_score_ 获取。
八、嵌套交叉验证
当我们想评估整个调优流程(包括参数搜索)的泛化性能时,需要使用嵌套交叉验证:
- 外层循环:划分训练/测试集,内层循环:对该训练集进行超参数搜索(含交叉验证),然后用得到的模型预测外层测试集。
- 最终分数是所有外层测试分数的平均值,避免了因调参而导致的测试集信息泄露。
核心原理通俗拆解
网格搜索:试遍所有菜谱
你想做一道最好吃的菜,有盐量(三种)、糖量(三种)、火候(三种)。你把所有 27 种组合都做一遍,请朋友打分(交叉验证),选出最好吃的配方。这就是网格搜索。
随机搜索:随机试菜
27 种组合太多,你只随机试其中的 10 种,大概率也能找到不错的配方,尤其当某些调料对味道影响不大时。
连续减半搜索:比赛淘汰制
先让 100 个选手(参数组合)初赛(用小数据),淘汰 50 个;剩下的复赛(用更多数据),再淘汰一半,直到决出冠军。这样比让所有选手直接比完整比赛更省时间。
底层数学逻辑
1. 交叉验证的方差与偏差
K 折交叉验证的均方误差估计的方差约为 σ²/K,K 越大,估计越稳定,但计算量也越大。通常取 K=5 或 10。
2. 随机搜索的收敛性
随机搜索在参数空间上采样,其找到最优解的概率与采样次数正相关。若最优解区域的体积占比为 p,则采样 n 次至少命中一次的概率为 1 - (1-p)^n。因此当参数空间很大时,随机搜索比网格搜索更高效。
3. 对数均匀分布
对于学习率 η,其有效范围往往跨越多个数量级(如 0.0001 到 0.1)。如果使用均匀分布,大多数点会集中在大值区域,小值区域被忽略。对数均匀分布使得在数量级上均匀采样,例如 10⁻⁴, 10⁻³, 10⁻² 等。
scikit-learn API详解
GridSearchCV
from sklearn.model_selection import GridSearchCV
grid = GridSearchCV(
estimator, # 模型对象
param_grid, # 参数网格字典
scoring=None, # 评估指标(字符串或可调用对象)
n_jobs=None, # 并行数
cv=5, # 交叉验证折数
verbose=0,
pre_dispatch='2*n_jobs',
return_train_score=False,
refit=True, # 是否用最佳参数在整个训练集上重新训练
error_score=np.nan
)
grid.fit(X_train, y_train)
print(grid.best_params_)
print(grid.best_score_)
best_model = grid.best_estimator_
test_score = best_model.score(X_test, y_test)
RandomizedSearchCV
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import uniform, loguniform, randint
param_dist = {
'C': loguniform(1e-3, 1e3),
'gamma': loguniform(1e-4, 1e-1),
'kernel': ['rbf', 'linear']
}
rand = RandomizedSearchCV(
SVC(), param_distributions=param_dist,
n_iter=50, cv=5, random_state=42, n_jobs=-1
)
rand.fit(X_train, y_train)
HalvingGridSearchCV / HalvingRandomSearchCV
from sklearn.experimental import enable_halving_search_cv
from sklearn.model_selection import HalvingRandomSearchCV
halving = HalvingRandomSearchCV(
estimator, param_distributions=param_dist,
n_candidates='exhaust', # 初始候选数
factor=3, # 每轮保留候选数的倒数
resource='n_samples', # 资源类型(样本数或迭代次数)
max_resources='auto',
min_resources='smallest',
random_state=42
)
环境配置与依赖安装
本课需要 scipy(用于参数分布)。
conda activate sklearn_tutorial
pip install scipy
完整代码实战(带详细注释)
实战1:GridSearchCV 基础——SVM 调参
# -*- coding: utf-8 -*-
"""
网格搜索 SVM 的 C 和 gamma 参数
数据集:手写数字二分类(0和1)
"""
from sklearn.datasets import load_digits
from sklearn.model_selection import train_test_split, GridSearchCV
from sklearn.svm import SVC
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
# 加载数据(二分类)
digits = load_digits()
mask = (digits.target == 0) | (digits.target == 1)
X, y = digits.data[mask], digits.target[mask]
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 创建 Pipeline(标准化 + SVM)
pipe = Pipeline([
('scaler', StandardScaler()),
('svm', SVC())
])
# 参数网格
param_grid = {
'svm__C': [0.1, 1, 10, 100],
'svm__gamma': [0.001, 0.01, 0.1, 1],
'svm__kernel': ['rbf']
}
grid = GridSearchCV(pipe, param_grid, cv=5, scoring='accuracy', n_jobs=-1, verbose=1)
grid.fit(X_train, y_train)
print("最佳参数:", grid.best_params_)
print("最佳交叉验证准确率: {:.4f}".format(grid.best_score_))
print("测试集准确率: {:.4f}".format(grid.score(X_test, y_test)))
实战2:RandomizedSearchCV 高效搜索
# -*- coding: utf-8 -*-
"""
随机搜索 SVM 的 C 和 gamma,使用对数均匀分布
"""
from sklearn.datasets import load_digits
from sklearn.model_selection import RandomizedSearchCV, train_test_split
from sklearn.svm import SVC
from sklearn.preprocessing import StandardScaler
from scipy.stats import loguniform
X, y = load_digits(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 标准化
scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)
param_dist = {
'C': loguniform(1e-2, 1e3),
'gamma': loguniform(1e-4, 1),
'kernel': ['rbf', 'linear']
}
rand = RandomizedSearchCV(SVC(), param_distributions=param_dist,
n_iter=50, cv=5, scoring='accuracy',
random_state=42, n_jobs=-1, verbose=1)
rand.fit(X_train_scaled, y_train)
print("最佳参数:", rand.best_params_)
print("最佳交叉验证准确率: {:.4f}".format(rand.best_score_))
print("测试集准确率: {:.4f}".format(rand.score(X_test_scaled, y_test)))
实战3:随机森林的网格搜索
# -*- coding: utf-8 -*-
"""
随机森林调参:n_estimators, max_depth, min_samples_split
"""
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split, GridSearchCV
X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
param_grid = {
'n_estimators': [50, 100, 200],
'max_depth': [10, 20, None],
'min_samples_split': [2, 5, 10]
}
rf = RandomForestClassifier(random_state=42)
grid = GridSearchCV(rf, param_grid, cv=5, scoring='accuracy', n_jobs=-1, verbose=1)
grid.fit(X_train, y_train)
print("最佳参数:", grid.best_params_)
print("最佳交叉验证准确率: {:.4f}".format(grid.best_score_))
print("测试集准确率: {:.4f}".format(grid.score(X_test, y_test)))
实战4:GBDT 调参(学习率与树数量)
# -*- coding: utf-8 -*-
"""
使用随机搜索优化 GBDT 的学习率、树数量、深度等
同时利用 early stopping 提前停止(但 RandomizedSearchCV 不支持动态早停,仅演示参数)
"""
from sklearn.ensemble import GradientBoostingClassifier
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import RandomizedSearchCV, train_test_split
from scipy.stats import loguniform, randint
X, y = load_breast_cancer(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
param_dist = {
'n_estimators': randint(50, 300),
'learning_rate': loguniform(1e-3, 0.5),
'max_depth': randint(2, 8),
'subsample': [0.7, 0.8, 0.9, 1.0],
'min_samples_split': randint(2, 20)
}
gbdt = GradientBoostingClassifier(random_state=42)
rand = RandomizedSearchCV(gbdt, param_dist, n_iter=30, cv=5,
scoring='roc_auc', random_state=42, n_jobs=-1)
rand.fit(X_train, y_train)
print("最佳参数:", rand.best_params_)
print("最佳交叉验证 AUC: {:.4f}".format(rand.best_score_))
print("测试集 AUC: {:.4f}".format(rand.score(X_test, y_test)))
实战5:分析 cv_results_ 可视化调参过程
# -*- coding: utf-8 -*-
"""
从 cv_results_ 中提取结果,绘制参数与分数关系图
"""
import matplotlib.pyplot as plt
import pandas as pd
import numpy as np
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import make_classification
from sklearn.model_selection import GridSearchCV
X, y = make_classification(n_samples=500, n_features=10, random_state=42)
param_grid = {
'n_estimators': [50, 100, 150, 200],
'max_depth': [5, 10, 15, 20]
}
rf = RandomForestClassifier(random_state=42)
grid = GridSearchCV(rf, param_grid, cv=3, return_train_score=True)
grid.fit(X, y)
results = pd.DataFrame(grid.cv_results_)
# 绘制 max_depth 固定时,n_estimators 对分数的影响
fig, axes = plt.subplots(1, 2, figsize=(12, 5))
for depth in [5, 10, 15, 20]:
subset = results[results['param_max_depth'] == depth]
axes[0].plot(subset['param_n_estimators'], subset['mean_test_score'], 'o-', label=f'depth={depth}')
axes[0].set_xlabel('n_estimators')
axes[0].set_ylabel('交叉验证准确率')
axes[0].legend()
axes[0].set_title('不同 max_depth 下 n_estimators 的影响')
# 热力图展示参数交互
pivot = results.pivot(index='param_max_depth', columns='param_n_estimators', values='mean_test_score')
im = axes[1].imshow(pivot.values, cmap='viridis', aspect='auto')
axes[1].set_xticks(range(len(pivot.columns)))
axes[1].set_xticklabels(pivot.columns)
axes[1].set_yticks(range(len(pivot.index)))
axes[1].set_yticklabels(pivot.index)
axes[1].set_xlabel('n_estimators')
axes[1].set_ylabel('max_depth')
axes[1].set_title('平均测试分数热力图')
plt.colorbar(im, ax=axes[1])
plt.tight_layout()
plt.show()
实战6:嵌套交叉验证评估泛化性能
# -*- coding: utf-8 -*-
"""
嵌套交叉验证:外层 CV 评估调优流程,内层 CV 进行参数搜索
避免因调参导致的测试集信息泄露
"""
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import cross_val_score, GridSearchCV, KFold
from sklearn.svm import SVC
from sklearn.preprocessing import StandardScaler
from sklearn.pipeline import Pipeline
X, y = load_breast_cancer(return_X_y=True)
# 定义 Pipeline 和参数网格
pipe = Pipeline([('scaler', StandardScaler()), ('svm', SVC())])
param_grid = {'svm__C': [0.1, 1, 10], 'svm__gamma': [0.01, 0.1, 1]}
# 内层 CV:GridSearchCV 自动做交叉验证
inner_cv = KFold(n_splits=5, shuffle=True, random_state=42)
outer_cv = KFold(n_splits=5, shuffle=True, random_state=42)
# 使用 cross_val_score 的 estimator 参数传入 GridSearchCV 对象
clf = GridSearchCV(pipe, param_grid, cv=inner_cv, scoring='accuracy')
nested_scores = cross_val_score(clf, X, y, cv=outer_cv, scoring='accuracy')
print(f"嵌套交叉验证平均准确率: {nested_scores.mean():.4f} (+/- {nested_scores.std():.4f})")
# 非嵌套的对比:直接在全部数据上做 GridSearchCV,再评估(会高估)
clf.fit(X, y) # 这已经污染了测试信息
print(f"非嵌套(全数据调参)最佳准确率: {clf.best_score_:.4f}")
实战7:HalvingRandomSearchCV 加速调参
# -*- coding: utf-8 -*-
"""
连续减半随机搜索,加快调参速度
"""
from sklearn.experimental import enable_halving_search_cv
from sklearn.model_selection import HalvingRandomSearchCV
from sklearn.datasets import make_classification
from sklearn.ensemble import RandomForestClassifier
from scipy.stats import randint, loguniform
X, y = make_classification(n_samples=2000, n_features=20, random_state=42)
param_dist = {
'n_estimators': randint(20, 200),
'max_depth': randint(3, 20),
'min_samples_split': randint(2, 20),
'max_features': loguniform(0.1, 1.0)
}
rf = RandomForestClassifier(random_state=42)
halving = HalvingRandomSearchCV(rf, param_dist, n_candidates='exhaust',
factor=3, resource='n_samples',
min_resources='smallest', cv=3,
random_state=42, n_jobs=-1, verbose=1)
halving.fit(X, y)
print("最佳参数:", halving.best_params_)
print("最佳交叉验证分数:", halving.best_score_)
实战8:自定义评分函数
# -*- coding: utf-8 -*-
"""
使用自定义评分函数进行调参(例如,F2 分数,更注重召回率)
"""
from sklearn.metrics import fbeta_score, make_scorer
from sklearn.model_selection import GridSearchCV
from sklearn.datasets import make_classification
from sklearn.ensemble import RandomForestClassifier
X, y = make_classification(n_samples=500, weights=[0.9], random_state=42)
# 自定义 F2 分数(beta=2,召回率权重更高)
f2_scorer = make_scorer(fbeta_score, beta=2)
param_grid = {'n_estimators': [50, 100], 'max_depth': [5, 10]}
rf = RandomForestClassifier(random_state=42)
grid = GridSearchCV(rf, param_grid, scoring=f2_scorer, cv=3)
grid.fit(X, y)
print("最佳参数(按 F2):", grid.best_params_)
print("最佳 F2 分数:", grid.best_score_)
案例实操演示
案例:完整调优流程(XGBoost 风格,使用 GBDT 模拟)
# 一个完整的调优流程:数据划分 -> 随机搜索 -> 细化网格搜索 -> 最终评估
from sklearn.datasets import fetch_california_housing
from sklearn.ensemble import GradientBoostingRegressor
from sklearn.model_selection import train_test_split, RandomizedSearchCV, GridSearchCV
from sklearn.metrics import mean_squared_error
from scipy.stats import loguniform, randint
# 加载数据
X, y = fetch_california_housing(return_X_y=True)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)
# 第一阶段:随机搜索宽范围
param_dist = {
'n_estimators': randint(50, 500),
'learning_rate': loguniform(0.01, 0.5),
'max_depth': randint(3, 10),
'subsample': [0.7, 0.8, 0.9, 1.0],
'min_samples_split': randint(2, 20)
}
gbdt = GradientBoostingRegressor(random_state=42)
rand = RandomizedSearchCV(gbdt, param_dist, n_iter=30, cv=3, scoring='neg_mean_squared_error',
random_state=42, n_jobs=-1)
rand.fit(X_train, y_train)
# 第二阶段:缩小范围,网格搜索精细调优
best_params = rand.best_params_
# 围绕最佳值附近构建网格
param_grid = {
'n_estimators': [max(50, best_params['n_estimators']-50), best_params['n_estimators'], best_params['n_estimators']+50],
'learning_rate': [best_params['learning_rate'] * 0.5, best_params['learning_rate'], best_params['learning_rate'] * 2],
'max_depth': [best_params['max_depth']-1, best_params['max_depth'], best_params['max_depth']+1],
'subsample': [best_params['subsample']-0.1, best_params['subsample'], best_params['subsample']+0.1],
}
# 清理超出范围的值
param_grid['n_estimators'] = [x for x in param_grid['n_estimators'] if x >= 10]
param_grid['max_depth'] = [x for x in param_grid['max_depth'] if x >= 1]
param_grid['subsample'] = [x for x in param_grid['subsample'] if 0 < x <= 1]
grid = GridSearchCV(gbdt, param_grid, cv=3, scoring='neg_mean_squared_error', n_jobs=-1)
grid.fit(X_train, y_train)
best_gbdt = grid.best_estimator_
y_pred = best_gbdt.predict(X_test)
rmse = mean_squared_error(y_test, y_pred, squared=False)
print(f"最终测试集 RMSE: {rmse:.4f}")
常见报错与避坑指南
报错1:ValueError: Invalid parameter ... for estimator
原因:参数名拼写错误,或参数不属于该模型(比如对 Pipeline 中的步骤需要加 步骤名__ 前缀)。
解决:使用 estimator.get_params().keys() 查看可用参数名。
报错2:UserWarning: One or more of the test scores are non-finite
原因:某些参数组合导致模型无法拟合(如 C 太大导致 SVM 不收敛)。
解决:设置 error_score=np.nan,或调整参数范围避免极端值。
报错3:n_iter 过大导致运行时间过长
解决:先用较小的 n_iter 探索,再细化范围。
报错4:网格搜索时内存爆炸
原因:n_jobs=-1 并行训练多个模型,每个模型会复制数据。
解决:减少 n_jobs,或使用 pre_dispatch 限制同时运行的作业数。
避坑总结
- 始终保留独立的测试集,调参时绝不触碰。
- 参数空间设计:对数量级差异大的参数(如学习率)使用对数分布。
- 交叉验证折数:数据量大时可用 3-5 折,小数据用 10 折。
- 优先随机搜索:当参数空间超过 3 维时,随机搜索效率更高。
- 利用
refit=True:搜索完成后再训练全量训练集,保证模型容量。
知识点总结
本课系统讲解了超参数自动调优的核心技术:
基础概念
- 交叉验证:在调参中提供稳定评估,防止过拟合验证集。
- 训练/验证/测试集划分:调参只在训练+验证上进行,测试集最后使用一次。
搜索方法
- 网格搜索:穷举候选组合,适合低维空间。
- 随机搜索:随机采样,效率高,支持分布采样。
- 连续减半搜索:迭代式淘汰,更快。
- 自定义评分:
make_scorer包装业务指标。
参数空间设计
- 列表:离散候选值。
- 整数范围:
randint。 - 均匀分布:
uniform。 - 对数均匀分布:
loguniform(用于跨度大的参数)。
结果分析
cv_results_:详细记录每次评估的结果。best_params_、best_score_、best_estimator_。
进阶
- 嵌套交叉验证:无偏估计调优流程的泛化性能。
- Pipeline 中的调参:使用
步骤名__参数名。
课后练习题
选择题
-
在超参数调优中,如果参数空间为 5 维,每维有 10 个候选值,网格搜索需要训练多少次模型(K=5 折)?
A. 5 B. 50 C. 50000 D. 250000 -
以下哪种参数分布最适合搜索学习率(0.0001 到 0.1)?
A. 均匀分布 B. 对数均匀分布 C. 整数均匀分布 D. 正态分布 -
嵌套交叉验证的目的是:
A. 加速调参 B. 无偏估计调参流程的泛化性能 C. 减少参数数量 D. 提高模型准确率
填空题
from sklearn.model_selection import RandomizedSearchCV
from scipy.stats import loguniform
# 1. 定义参数分布
param_dist = {
'C': loguniform(1e-3, 1e3),
'gamma': ________(1e-4, 1e-1) # 使用 loguniform
}
# 2. 创建随机搜索对象,迭代 30 次,5 折交叉验证
rand = RandomizedSearchCV(SVC(), param_dist, n_iter=30, cv=5, random_state=42)
# 3. 训练
rand.fit(X_train, y_train)
# 4. 获取最佳参数
best_params = rand.________
# 5. 获取最佳分数
best_score = rand.________
实操题
-
网格搜索随机森林:在
load_breast_cancer数据集上,使用GridSearchCV搜索随机森林的n_estimators([50,100,150])和max_depth([5,10,None])。输出最佳参数和测试准确率。 -
随机搜索 SVM:在
load_digits全量数据(10类)上,使用RandomizedSearchCV搜索 SVM 的C(对数均匀 0.001~1000)和gamma(对数均匀 0.0001~1),迭代 50 次。绘制参数与分数的散点图,分析哪些区域分数高。 -
自定义评分与早停:在
make_classification生成的不平衡数据(正例 5%)上,使用RandomizedSearchCV搜索 GBDT 的参数,评分指标使用fbeta_score(beta=2)。输出最佳参数,并对比使用accuracy评分的结果有何不同。
思考题
假设你有一个包含 10 万样本、200 个特征的数据集,你需要训练一个随机森林,并调优它的 4 个超参数。你估计网格搜索需要 5000 次训练,每次训练需要 1 秒(K=5 折,每个模型 0.2 秒),总时间约 5000 秒,太长了。请设计一个分阶段的调优策略,在总时间控制在 1000 秒左右的情况下,尽可能找到好的参数组合。写出你的方案和理由。
下一课预告:第30课(项目实战专属)我们将完成一个工业级综合项目——机器学习全流程项目落地,涵盖从业务分析到模型部署的完整链路。这是专栏的收官之作,敬请期待!
🔗《30节课 scikit-learn 从入门到精通》系列课程导航
第一部分:基础入门 & 环境准备(1-6 课)
第二部分:数据预处理 & 数据集操作(7-12 课)
第三部分:传统机器学习回归算法(13-17 课)
第四部分:分类算法精讲(18-23 课)
第五部分:聚类 & 降维 & 集成学习(24-29 课)
第六部分:结业大型项目实战(第 30 课)
🌟 感谢您耐心阅读到这里!
💡 如果本文对您有所启发欢迎:
👍 点赞📌 收藏 📤 分享给更多需要的伙伴。
🗣️ 期待在评论区看到您的想法, 共同进步。
🔔 关注我,持续获取更多干货内容~
🤗 我们下篇文章见~

3906

被折叠的 条评论
为什么被折叠?



