12.3 机器学习入门:训练集、测试集、过拟合
课前导读
本节目标
你将学会:理解训练集、测试集、过拟合和数据泄露,知道机器学习在量化中是验证工具,不是收益捷径。
适合对象:已经学过 Python、因子、回测和 walk-forward 思维,准备接触机器学习的 A 股投资者。
难度:advanced
预计用时:约 45 分钟
机器学习听起来很强大。
但在量化投资里,它最容易被误解。
很多人以为模型越复杂,收益越高。
更专业的理解恰好相反:模型越复杂,越需要严格验证。
机器学习不是让电脑替你发现确定答案。
它更像让一个学生在历史样本上做题,然后用从未见过的题目检查是否真正理解。
如果学生只是背答案,考试一换题就失效。
这就是过拟合。
知识正文
1. 类比:模型像学生刷题
把历史数据想象成题库。
特征是题干里的信息。
标签是标准答案。
模型是学生。
训练就是学生做题、改错、总结规律。
测试就是拿一套他从未见过的新卷子检验能力。
如果学生把题库答案背得滚瓜烂熟,训练成绩可能满分。
但新卷子一来就露馅。
A 股机器学习研究也一样。
一个模型可以在 2018-2021 年样本里表现惊人。
但如果 2022-2024 年样本外表现很差,它就没有通过真正考试。
关键直觉
机器学习不是“让模型更聪明”,而是“用更严格的方式检验模型有没有偷懒”。
2. 术语一:特征和标签
特征通常记作 X。
它们是模型在做判断时可以看到的信息。
例如:过去 20 日涨跌幅、换手率、波动率、ROE、PE 分位数、公告后天数。
标签通常记作 y。
它是你希望模型学习或预测的目标。
例如:未来 20 日收益、未来是否跑赢行业、未来回撤是否超过某个阈值。
关键边界是:特征必须在决策时可见。
标签可以来自未来,因为它是训练答案。
但标签绝不能混进特征。
如果未来收益被错误地放入特征,模型会显得极其准确。
这不是能力,是作弊。
3. 术语二:训练集、验证集、测试集
训练集用于让模型学习规律。
验证集用于选择模型、参数或特征组合。
测试集用于最后评估,应该尽量保持“只看一次”。
在金融时间序列中,不能像普通表格那样随机打乱。
更合适的方式是按时间切分。
例如:
| 数据区间 | 用途 | 注意事项 |
|---|---|---|
| 2016-2020 | 训练集 | 模型在这里学习关系 |
| 2021-2022 | 验证集 | 调整参数和特征 |
| 2023-2024 | 测试集 | 最后检验,不反复调参 |
如果你看了测试集结果后,又回去改特征,再把同一测试集当最终结果,就等于把考试题也拿来训练。
这会让结果虚高。
常见误区
“测试集表现不好,我再改几个参数直到变好”不是严谨优化,而是在逐步污染测试集。
4. 术语三:过拟合
过拟合就是模型把历史噪声当规律。
它像学生不仅背了题目答案,还背了题号、排版和错别字。
在 A 股里,过拟合常见于:
- 特征太多,样本太少。
- 参数试得太多,只展示最好的一组。
- 训练期太短,刚好覆盖某个单一行情。
- 忽略成本、滑点、涨跌停和停牌。
- 用未来数据、修正后财务数据或幸存者股票池。
过拟合的危险在于:它会给研究者很强的确定感。
回测曲线越漂亮,越容易让人忽视背后的偷看、筛选和噪声。
专业研究者看到异常漂亮的结果,第一反应不是兴奋,而是怀疑。
5. 欠拟合:模型太粗也不行
欠拟合是另一端。
模型太简单,连基本关系都抓不住。
例如你只用“今天涨了就明天买”解释所有 A 股。
它可能忽略行业、流动性、市值、波动、市场阶段等重要差异。
欠拟合的表现是训练集和测试集都不太好。
过拟合的表现是训练集很好,测试集明显变差。
机器学习研究不是追求最复杂。
而是在欠拟合和过拟合之间寻找可解释、可复核、可承受的平衡。
6. 模型复杂度:工具箱不是越满越好
常见机器学习模型包括线性模型、树模型、集成模型和神经网络。
本节不要求你掌握算法细节。
你先把它们理解成不同形状的尺子。
线性模型像直尺,简单、可解释,但表达能力有限。
树模型像一组判断题,能处理非线性关系,但容易记住噪声。
集成模型像多个学生投票,稳定性可能更好,但解释成本更高。
神经网络像很复杂的函数机器,对数据量、验证和工程要求更高。
对于 A 股日频选股,最重要的不是模型名字。
而是数据可得性、样本外验证、成本约束和风险边界。
7. A 股案例:预测未来 20 日相对收益
假设你想让模型判断哪些股票未来 20 日可能跑赢同类股票。
这不是让模型预测精确涨幅。
更现实的目标是做排序:把股票分成相对更强和更弱。
可用特征可以来自你已经学过的内容:
| 特征类别 | 示例 | 直觉 |
|---|---|---|
| 动量 | 过去 20 日涨跌幅 | 市场近期是否认可 |
| 波动 | 过去 20 日收益标准差 | 持有过程是否颠簸 |
| 成交 | 换手率、成交额变化 | 资金关注是否变化 |
| 质量 | ROE、经营现金流质量 | 公司赚钱是否扎实 |
| 估值 | PE、PB 分位数 | 当前价格是否偏贵 |
标签可以是未来 20 日收益在行业内的排名。
这样做比预测绝对涨跌更稳一点,因为它减少了全市场涨跌的干扰。
但它仍然不能保证实盘收益。
模型只是在历史样本里学习排序线索。
市场风格切换时,线索可能失效。
8. 不偷看答案的数据流程
一个安全的数据流程应该强调时间顺序。
graph TD
A["收集当时可见数据"] --> B["构造特征 X"]
B --> C["构造未来标签 y"]
C --> D["按时间切分训练和测试"]
D --> E["只在训练集学习"]
E --> F["在测试集评估"]
F --> G["记录边界和失败样本"]注意这里的“未来标签”只用于训练答案。
它不能流回特征构造环节。
如果流程图里从标签回到特征,你就要高度警惕。
量化开发时,可以把每一列标注为:
- 特征列。
- 标签列。
- 辅助列。
- 不允许用于训练的审计列。
这会显著降低无意泄露的概率。
9. 简短伪代码:按时间切分
下面不是完整机器学习教程,只展示安全切分思路。
features = ["momentum_20", "turnover_20", "volatility_20", "roe_lagged"]
label = "next_20d_rank"
train = data[data["date"] < "2021-01-01"]
valid = data[(data["date"] >= "2021-01-01") & (data["date"] < "2023-01-01")]
test = data[data["date"] >= "2023-01-01"]
# model.fit(train[features], train[label])
# valid_score = evaluate(model, valid[features], valid[label])
# test_score = evaluate(model, test[features], test[label])请注意 roe_lagged。
财务数据必须按披露日滞后处理。
不能把年报期末日期当成可见日期。
如果 2023 年 4 月才披露的年报被模型用于 2023 年 1 月决策,就是泄露。
10. 评估机器学习模型,不只看准确率
A 股量化模型常常不是简单二分类。
即便模型能把上涨和下跌分对 55%,也不代表能交易。
你还要看:
- 分组收益是否单调。
- 前 10% 股票是否真的优于后 10%。
- 换手率是否过高。
- 交易成本是否吞掉优势。
- 最大回撤是否可承受。
- 行业和风格暴露是否过于集中。
- 测试期是否覆盖不同市场环境。
机器学习模型最终要回到投资问题:它是否提供了更稳的排序信息,是否能被风控和组合约束接住。
11. 专业老师、投资者、开发者三重视角
老师视角:先讲清楚训练、测试和过拟合,再讨论模型算法。
投资者视角:模型输出只是概率倾向,不是买入命令。
量化开发视角:要让特征、标签、切分、参数和结果全部可复现。
如果一个模型无法解释数据来源、可得时间和评估边界,即使回测很好,也不能轻易进入实盘流程。
12. 不要神化模型
机器学习擅长从大量特征中寻找复杂关系。
但金融市场有噪声、有制度、有交易约束、有参与者博弈。
模型学到的关系可能很快被市场环境覆盖。
你真正要追求的不是“模型替我赚钱”。
而是“模型是否比简单规则更严格、更稳定地验证我的想法”。
交互实验室
练习 1:找出偷看答案的位置
请阅读下面流程,并指出风险。
- 下载 2018-2024 年所有股票数据。
- 计算每只股票未来 20 日收益。
- 用未来 20 日收益最高的股票构造“优质股票池”。
- 再用这个股票池训练模型。
- 得到很高测试收益。
问题在哪里?
答案:第 3 步已经使用未来收益筛选股票池。
这会让后续训练和测试都站在被未来答案污染的样本上。
正确做法是用当时可见条件构造股票池,例如上市时间、非 ST、流动性、行业分类等。
练习 2:设计一次安全考试
请为一个选股模型填写下表。
| 项目 | 你的设计 |
|---|---|
| 训练期 | 例如 2016-2020 |
| 验证期 | 例如 2021-2022 |
| 测试期 | 例如 2023-2024 |
| 特征 | 只写当时可见字段 |
| 标签 | 未来 20 日行业内收益排名 |
| 成本假设 | 佣金、印花税、滑点、无法成交处理 |
| 失败标准 | 测试期分组不单调或回撤超过边界 |
请特别写下“我不会因为测试期不好看而反复调参”。
这句话是给研究纪律上的锁。
练习 3:判断过拟合迹象
以下现象中,哪些提示过拟合风险?
- 训练集收益曲线几乎直线上升,测试集明显回撤。
- 参数从 19 改到 20,结果差别巨大。
- 只展示最好的一年,不展示其他年份。
- 模型需要 300 个特征,但有效样本很少。
- 扣除双倍滑点后优势消失。
参考答案:全部都需要警惕。
它们分别对应样本外崩塌、参数孤岛、选择性展示、特征过多和成本脆弱。
核心复盘
知识清单:
- [ ] 我能用“学生刷题”解释训练集和测试集。
- [ ] 我知道特征是当时可见信息,标签是未来答案,二者不能混淆。
- [ ] 我理解过拟合是把历史噪声当规律。
- [ ] 我会按时间切分数据,而不是随机打乱金融时间序列。
- [ ] 我能用样本外表现、成本和风险边界评估模型。
金句总结
机器学习不是替你跳过验证,而是要求你把验证做得更严格。