3、网格搜索法:全网格搜索原理、实现步骤、优缺点分析、适用场景
说到参数优化,网格搜索法可能是最直观、最容易理解的方法了。我刚开始做量化的时候,第一个接触的优化方法就是它。说白了,就是把所有可能的参数组合都试一遍,然后挑出最好的那个。
你可能会问:这么简单粗暴的方法,真的有用吗?嗯,有用,但得看场景。让我慢慢给你拆解。
3.1 全网格搜索的原理
网格搜索的核心思想其实就四个字:穷举遍历。
假设你的策略有两个参数:n1(短期均线周期)和 n2(长期均线周期)。你想知道 n1 在 5 到 20 之间、n2 在 20 到 60 之间哪个组合最好。网格搜索会怎么做?它会生成一个二维网格:
- n1 取 5, 6, 7, ..., 20(共 16 个值)
- n2 取 20, 25, 30, ..., 60(共 9 个值)
- 总共 16 × 9 = 144 个组合
然后,对每个组合跑一遍回测,记录下绩效指标。最后,从这 144 个结果里挑出最优的那个。
我画了一张图,帮你理解这个网格结构:
每个红点代表一个参数组合,橙色圈出来的就是最优解。你看,思路就是这么简单。
3.2 实现步骤
网格搜索的实现步骤,我一般分成五步走:
- 定义参数空间:确定每个参数的取值范围和步长
- 生成参数网格:用笛卡尔积生成所有组合
- 遍历评估:对每个组合跑回测,记录绩效
- 结果排序:按目标指标(如夏普比率)排序
- 选择最优:挑出排名靠前的组合
给你看一段 Python 代码,这是我常用的实现方式:
import itertools
import numpy as np
import pandas as pd
def grid_search(strategy_func, param_grid, data, metric='sharpe'):
"""
全网格搜索实现
:param strategy_func: 策略函数,接收参数和data,返回绩效指标
:param param_grid: 参数字典,如 {'n1': range(5, 21, 1), 'n2': range(20, 61, 5)}
:param data: 历史数据
:param metric: 优化目标指标
"""
results = []
# 生成所有参数组合
keys = param_grid.keys()
values = param_grid.values()
total = 1
for v in values:
total *= len(v)
print(f'总组合数: {total}')
# 遍历所有组合
for combo in itertools.product(*values):
params = dict(zip(keys, combo))
# 跑回测
perf = strategy_func(params, data)
results.append({
**params,
metric: perf[metric]
})
# 转成DataFrame并排序
df = pd.DataFrame(results)
df = df.sort_values(metric, ascending=False)
return df
# 使用示例
param_grid = {
'fast_ma': range(5, 21, 1),
'slow_ma': range(20, 61, 5)
}
# result = grid_search(my_strategy, param_grid, hist_data)
# print(result.head(10))
3.3 优缺点分析
网格搜索的优点很明显,但缺点也同样致命。我直接给你列个表,一目了然:
| 维度 | 优点 | 缺点 |
|---|---|---|
| 完整性 | 覆盖所有组合,不会遗漏 | 组合数随参数数量指数增长 |
| 可解释性 | 结果直观,容易理解 | 无法处理参数间的非线性关系 |
| 实现难度 | 代码简单,容易上手 | 计算资源消耗大 |
| 并行化 | 天然可并行,加速容易 | 对连续参数空间有离散误差 |
| 过拟合风险 | — | 容易在历史数据上过拟合 |
我来说说几个关键点:
维度灾难——这是网格搜索最大的敌人。假设你有 5 个参数,每个参数取 10 个值,那就是 10^5 = 10 万次回测。如果每次回测需要 1 秒,那就是 27 个小时。你想想看,这还只是 5 个参数。
离散化误差——网格搜索只能检查你定义的离散点。最优解可能恰好落在两个网格点之间。我曾经遇到过这种情况:步长设为 5 时找不到好结果,改成步长 3 反而找到了。嗯,这里要注意。
3.4 适用场景
网格搜索不是银弹,它有自己的用武之地。我个人总结了几类适合的场景:
- 参数数量少(≤3个):这时候计算量可控,全网格搜索是最稳妥的选择
- 参数空间较小:比如每个参数只有 5-10 个候选值
- 需要可解释性:当你需要向团队或客户解释优化过程时,网格搜索的直观性是个大优势
- 作为基准方法:在尝试更复杂的优化方法前,先用网格搜索跑一遍,看看最优解的大致位置
- 参数是离散值:比如选择哪几根均线、使用哪个技术指标,这些天然就是离散的
不适合的场景也很明显:
- 参数超过 4 个——计算量会爆炸
- 参数是连续值——离散化会丢失精度
- 需要快速迭代——网格搜索太慢了
我的建议: 网格搜索最适合做「初步探索」。先用大步长、少参数跑一遍,找到大致的「好区域」,然后再用更精细的方法(比如贝叶斯优化)去深入挖掘。别一上来就搞全网格,那是给自己找麻烦。
说白了,网格搜索就像用筛子筛沙子。筛子孔太大,会漏掉好东西;孔太小,又筛得太慢。关键是要找到那个平衡点。
好了,网格搜索就讲到这里。下一节我们聊聊随机搜索,它能在一定程度上解决网格搜索的「维度灾难」问题。到时候我会告诉你,为什么有时候「随机」反而比「全量」更聪明。
公众号:蓝海资料掘金营,微信deep3321