4. 网格搜索(Grid Search)原理与Python实现
4.1 什么是网格搜索
网格搜索,说白了就是暴力试参数。你定好一组候选值,程序把所有组合跑一遍,挑出表现最好的。
我刚开始调参时总嫌它“笨”,觉得有优化算法为啥还用手动?结果有一次项目 deadline 压得很紧,随机搜索跑了几百次都没找到稳定区域,最后靠网格搜索把关键参数一网打尽。嗯,从那以后我对它的态度就变了——简单不一定没用,关键看场景。
它的核心逻辑就三步:
- 定义参数网格(每个参数取哪些值)
- 对网格中所有组合,用交叉验证评估模型
- 选平均分数最高的那组参数
4.2 搜索空间与组合爆炸
网格搜索最大的坑是什么?组合数太多,跑不动。假设你有两个参数:max_depth 取 5 个值,n_estimators 取 10 个值,那就要跑 50 次;如果再加一个 min_samples_split 取 4 个值,就是 200 次。再乘以 5 折交叉验证,就是 1000 次训练。
表格里我列了常见搜索方式的对比,你感受一下:
| 方法 | 策略 | 搜索次数(示例) | 适用场景 |
|---|---|---|---|
| 网格搜索 | 穷举所有组合 | 高(组合数乘积) | 参数少(≤3)、取值范围已知 |
| 随机搜索 | 随机采样 | 中(可指定次数) | 参数多、计算资源有限 |
| 贝叶斯优化 | 基于历史结果选点 | 低(几十次) | 参数多、单次训练成本高 |
4.3 Python实现:用Scikit-learn搞定
最直接的工具就是 GridSearchCV。来,看个完整的栗子:
from sklearn.model_selection import GridSearchCV
from sklearn.ensemble import RandomForestClassifier
from sklearn.datasets import load_iris
# 加载数据
X, y = load_iris(return_X_y=True)
# 定义模型
model = RandomForestClassifier(random_state=42)
# 定义参数网格
param_grid = {
'n_estimators': [50, 100, 200],
'max_depth': [3, 5, None],
'min_samples_split': [2, 5, 10]
}
# 网格搜索 + 5折交叉验证
grid = GridSearchCV(
estimator=model,
param_grid=param_grid,
cv=5,
scoring='accuracy',
n_jobs=-1, # 用所有CPU
verbose=1
)
# 开跑
grid.fit(X, y)
# 输出最佳参数
print("Best params:", grid.best_params_)
print("Best score:", grid.best_score_)
跑完之后,grid.best_params_ 就是你的最优参数组合。grid.best_score_ 是对应的平均交叉验证分数。
4.4 结果怎么看
光拿到最佳参数还不够,我建议你把所有组合的分数都看一眼。有时候次优参数更稳定——我在项目中就遇到过这种情况:最优参数在验证集上高 0.5%,但测试集上反而掉 2%,明显过拟合了。
用 cv_results_ 可以拿到全部明细:
import pandas as pd
results = pd.DataFrame(grid.cv_results_)
# 只选关心的列
cols = ['params', 'mean_test_score', 'std_test_score']
print(results[cols].sort_values('mean_test_score', ascending=False))
输出类似:
params mean_test_score std_test_score
0 {'n_estimators': 100, 'max_depth': 5, ...} 0.9733 0.0231
12 {'n_estimators': 200, 'max_depth': 5, ...} 0.9667 0.0302
... ... ...
注意看 std_test_score——标准差大意味着模型在不同折上表现不稳定,这种参数组合要小心。
4.5 优点与局限
- 优点:结果可复现、理解直观、能找到全局最优(在给定网格内)
- 缺点:计算量随参数数量指数增长;对连续参数只能做粗离散化
什么时候别用?参数维度超过 4 个,或者单次训练就要半小时以上。这时候你强行上网格搜索,等结果出来项目都黄了。
4.6 完整流程图
下面这张图把整个流程串起来了,你跟着箭头走一遍就能记住。仔细看,每个分支都在强调“组合”和“评估”:
这条线走下来很清晰:先搭网格,再挨个试,最后挑最好的。记住这个流程,以后遇到调参任务,不至于手忙脚乱。