Py学习  »  机器学习算法

机器学习在量化领域里,真实产出接近零?回测一下不就知道咯?!

窥市寻真 • 1 周前 • 88 次点击  

量化研究 · 机器学习

机器学习在量化领域里,真实产出接近零?

18 个指数、130 个月、25 张回测图

创作|程飞  编辑|程飞

正文共:8,275 字,预计阅读时间:21 分钟

截至 2026 年 10 月 27 日收盘,沪深300 报 4049.55 点,年内累计下跌 13.96%,最近 60 个交易日跌去 17.50%,最近 20 个交易日又反弹 4.10%。同一时间,私募排排网的口径显示,2026 年前 4 个月中证500 指增产品的平均超额只剩 1.93%,中证1000 指增是 3.24%。而在 2020 年到 2023 年,百亿量化在中证500 指增上的年度超额,中位数和平均值都超过 10%,个别年份高于 20%。四年时间,同一条产品线,超额缩了一个数量级。这篇文章想说的就是这件事:不是模型变笨了,是我们一直把功劳记在了错的地方。

今天,我把机器学习在量化里能做的事情,拆成一个可以算清楚的实验:18 个指数、203 个月的数据、14 个截面特征、5 类模型、130 个月的样本外滚动检验。我本来想写一篇“机器学习如何重塑量化”的文章,写到一半发现数据不支持这个标题。于是我换了个写法:先把这个接近零的结果摆出来,再解释为什么它接近零,最后说清楚机器学习真正改变的东西是什么。

这篇文章会得罪两种人。一种是把模型复杂度当成护城河的人,另一种是相信“多喂数据就能变强”的人。

一、先把实验说清楚

任何不谈口径的结论都是耍流氓,所以我先把口径钉死。

标的池是 18 个指数:沪深300、上证50、中证500、中证1000、创业板指、科创50,加上能源、消费、医药、金融、信息、白酒、银行、证券、军工、环保、全指医药、全指信息。数据来自公开行情接口,最早一路追到 2002 年,样本外从 2016 年 1 月开始,到 2026 年 9 月结束,正好 130 个月。

特征 14 个,都是不用花钱买的东西:1、3、6、12 个月动量,1 个月和 3 个月波动率,波动率之比,价格对 20 日和 60 日均线的偏离,过去一年的回落幅度,偏度,峰度,对沪深300 的 beta,以及成交量的相对变化。标签只有一个:下个月这个标的在截面里的排名,映射到 -0.5 到 0.5 之间。

模型 5 类:岭回归、逻辑回归、随机森林、梯度提升树、一个小型神经网络,再加一个把后三者排名平均的三模型集成。训练方式是严格滚动的扩展窗口,每月用截止当月之前的全部历史重新拟合,预测下个月,绝不回头改参数。组合规则也定死:每月按预测分取前 3 名等权持有,单边成本 10 个基点。

这里必须坦白一个局限:这是指数层面的横截面,不是个股。个股层面有几千个标的、更干净的标签、更丰富的另类数据,机器学习的边际价值会比这个大得多。我选指数,是因为它足够干净、足够可复现,也足够残酷。它能把“模型到底有没有信息”这件事,从噪音里剥出来。

二、五种模型,一个结果

先看结果。130 个月跑下来,五种模型的年化净值增速分别是:线性回归 -1.41%,逻辑回归 1.72%,随机森林 -0.77%,梯度提升树 -4.45%,神经网络 -0.78%,三模型集成 -3.42%。同一段时间,等权持有全池是 1.27%,沪深300 是 1.87%。

换句话说,五种模型,没有一种跑赢最简单的等权持有。而且注意一个细节:模型越复杂,结果越差。梯度提升树是这里最“现代”的模型,它的年化是 -4.45%,最大回落 -60.92%,比等权基准的 -35.39% 深了 25 个百分点。神经网络赢了月胜率,52.3%,但年化还是负的,因为它赢的时候赢得少,输的时候输得多。

模型
年化
波动
夏普
最大回落
线性回归
-1.41%
21.30%
-0.07
-48.75%
逻辑回归
1.72%
20.64%
0.08
-47.63%
随机森林
-0.77%
20.09%
-0.04
-48.12%
梯度提升树
-4.45%
21.90%
-0.20
-60.92%
神经网络
-0.78%
21.77%
-0.04
-45.44%
三模型集成
-3.42%
21.48%
-0.16
-55.77%
等权全池
1.27%
19.79%
0.06
-35.39%
沪深300
1.87%
18.47%
0.10
-39.92%

这张图第一次看的时候我有点不舒服。六条线缠在一起,谁也没有真正甩开谁。我们习惯看到的那种“机器学习吊打传统因子”的图,通常来自两个地方:一是样本内,二是只展示表现最好的那一段。把时间轴拉满、把成本算进去、把每个月都算进去,曲线的形状就变成这样了。

右边那张图更直接:横轴是年化,纵轴是最大回落,越靠左上越好。五个点挤在一个很小的区域里,没有一个点完成“更高年化、更浅回落”的位移。集成模型看起来稳一点,那是它把三份错误平均掉的副产品,不是它更懂市场。

模型选型是量化研究里最让人上瘾、也最不重要的一件事。同一批特征喂给线性模型和梯度提升树,结果差不到 6 个百分点,而这 6 个百分点全部在噪音里。真正的差距,发生在模型开始训练之前。

三、十八个标的,2.68 个赌注

为什么模型没用?我最先怀疑的是特征不够。后来发现,问题出在标的上。我把 18 个指数的日涨跌拿去做主成分分解,结果是这样的:第一主成分解释了 57.0% 的方差,第二主成分 19.7%,第三主成分 7.0%,三个加起来 83.7%。特征值大于 1 的主成分只有 3 个。按参与率算,这 18 个指数的有效独立维度是 2.68。

这意味着什么?意味着你名义上有 18 个选择,实际上只有不到 3 个独立的赌注。你买沪深300 和买上证50,在很多月份里是同一笔暴露;你买消费和买白酒,也经常是同一笔暴露。模型再聪明,它能分配的信息量上限就是这 2.68 维。它不可能从三个维度里凭空变出二十种独立的判断。

为了验证,我做了一组宽度实验:每月随机抽 5、8、11、14、18 个标的参与排序,其他一切不变。结果样本外平均 IC 分别是 0.0169、0.0277、0.0199、0.0338、0.0096,误差棒重叠得厉害,没有单调关系。把标的从 5 只加到 18 只,IC 没有变好。

这个结果让我改了一个长期持有的看法。过去我也相信“标的池越大,机器学习越有用”,现在我会补一句:前提是新增的标的带来新的独立维度,而不是把同一个暴露再复制一遍。从 500 扩到 1000、扩到 3000,如果扩进来的都是同一种风格、同一种流动性的资产,宽度是名义的,模型拿到的是 3000 个高度相关的样本,不是 3000 个独立判断。

这一节是全文最想让你记住的地方。机器学习吃的是“独立样本的数量”,不是“数据的行数”。当你的标的池只有 2.68 个独立维度时,喂给它一亿行数据,它学到的仍然只是 2.68 个维度的历史剧本。

四、单因子 0.068,进模型归零

再看另一个反常识的地方。单个因子的 IC 其实不难看:12 个月动量 0.0684,波动率之比 0.0569,过去一年回落幅度 0.0491,峰度 -0.0551,beta -0.0486。在 A 股,月度 IC 到 0.05 已经算能用的东西了。

但是把这 14 个特征一起喂给模型,IC 变成了:岭回归 0.0140,逻辑回归 0.0260,随机森林 -0.0072,梯度提升树 -0.0051,神经网络 0.0153,集成 -0.0001。最好的 0.026,只有单因子 0.068 的三分之一。

为什么会这样?我后来想明白了,原因不复杂:这些因子在不同年代的方向是相反的,模型把它们平均掉了。12 个月动量在 2012 年到 2013 年平均 IC 是 +0.16 和 +0.18,在 2014 年是 -0.29,在 2022 年是 -0.13。你把这些年份混在一起训练,模型看到的是“动量有时候有用、有时候有害”,最优解就是给一个接近零的权重。它没有犯错,它只是太诚实。

置换重要性的图更难看。2024 年以后的样本外,我把每个特征单独打乱,看 IC 怎么变。结果是几乎全为负:打乱 beta,IC 从 -0.052 变成 +0.027;打乱 3 个月波动,IC 提升 0.035。翻译成人话:这些特征在这个模型里的组合方式,是在帮倒忙。模型不是没学到东西,是学到了一套在样本外反向生效的东西。

五、样本内 0.61,样本外 0.00

这一节是整篇文章里最不需要修辞的部分。每个月,我用截至当月的全部历史训练模型,然后在最近 12 个月的训练样本上回看它的 IC。130 个月平均下来,样本内 IC 是 0.6066。而同一批模型在下一个月的样本外 IC,均值是 -0.0051。

0.61 和 0.00 之间那 0.61,就是模型记住的历史。过拟合不是一个概率问题,它是一笔固定成本。你每训练一次,就要为这份记忆付一次费,付的方式是样本外的真实表现归零。右边那张散点图更狠:横轴样本内 IC 越漂亮,纵轴下个月的样本外 IC 并不跟着变好,散点是一团糊在原点附近的云。

我也试过靠增加训练数据来解决。训练窗口从 24 个月拉到 84 个月,样本外 IC 分别是 -0.0311、0.0162、0.0167、-0.0139、0.0247。没有趋势,就是在一个很窄的区间里随机跳动。

这条曲线打掉了一个很流行的信念:数据越多,模型越强。在独立维度只有 2.68 的世界里,加数据只是让模型把同一段历史记得更牢。学习曲线早早走平,不是因为它学够了,是因为它已经没有新的东西可学。

六、IC 不是衰减,是翻符号

行业里有一个用得很顺口的词,叫“因子衰减”。它暗示信号是一条慢慢变弱的曲线,像电池放电。我这十年看到的不是这样。我把 12 个月动量的 IC 按年拆开,看到的是一根根上下翻的柱子。

2012 年 +0.16,2013 年 +0.18,2014 年 -0.29,2015 年 -0.16,2016 年 +0.16,2018 年 -0.15,2020 年 +0.15,2021 年 -0.12,2022 年 -0.13,2026 年至今 +0.20。这不是衰减,这是反向。信号没有变弱,是市场在换剧本。同一个“强者继续强”的逻辑,在增量资金入场的年份成立,在存量博弈、风格切换的年份会直接反噬。

月度 IC 的均值是 -0.0001,胜率 51.5%,看着像抛硬币。但累计 IC 的曲线不是一条直线,它有两段明显的走平,甚至下折。走平的那两段,正好是模型集体失灵的窗口。如果只看一个全样本均值,你会以为这个模型“平平无奇”;把时间轴拉开,你会看到它是“在一半时间里帮倒忙”。

这也解释了为什么很多策略的尽调报告看不出问题:它们展示的是全周期年均值,而不是分期表现。年均值会把方向相反的年份对冲掉,剩下的那个数字看起来很温和,温和到没有任何信息。

七、模型在说一年,你在按月调

接下来这张图,是我今年最想重做的一张图。我把同一批预测值,拿去和不同持有期的真实表现做相关性,得到 1、2、3、6、12 个月的 IC,分别是 -0.0001、-0.0107、-0.0131、+0.0123、+0.0194。

注意这个形状:短周期是负的,长周期才转正。模型的预测里没有“下个月谁涨”的信息,只有“未来一年谁的相对位置更稳”的信息。而我的组合是按月调仓的。这意味着我每个月都在用一个一年期的判断做一个月期的决策,中间那 11 个月的噪音,全部变成了交易成本。

为了验证这个解释,我做了一组标签实验:特征不变、模型不变、组合规则不变,只把训练标签从“未来 1 个月排名”换成“未来 3 个月排名”和“未来 6 个月排名”。结果是年化 -3.96%、+1.38%、+6.50%。

同一个模型,只换标签,年化差 10.46 个百分点,而且 6 个月标签的那条线,跑赢了等权基准 1.27%。这是整个实验里唯一一组稳定跑赢的配置。它说明的东西比“模型有用”重要得多:决定结果的是你怎么定义“正确”,不是你怎么拟合它。

五分组也印证了这一点:Q1 到 Q5 的年化分别是 -0.90%、1.38%、0.92%、1.41%、1.55%。两端拉开了差距,中间三档乱序。说明模型确实有排序能力,但这份能力只值 2.45 个百分点,且大部分来自“别选最差的那一档”,而不是“找到最好的那一档”。

多空价差是另一个容易自我欺骗的地方。Q5 减 Q1,年化只有 0.85%,月均 0.15%,夏普 0.06。把它画成累计曲线,你会看到一条斜率很小、还很颠簸的线。而很多研报里的“多空价差”之所以漂亮,是因为它们既没扣成本,也没考虑做空约束,更没考虑这 0.85% 的容量根本撑不起一个产品。

八、换手是隐形税

我的组合规则是每月取前 3 名,看起来非常“低换手”。实际跑出来,月度双边换手率平均 136.2%。因为每月的前 3 名几乎全换,模型每个月都在给你一份新的名单。

136% 的月度双边换手,配上单边 10bp,一年就是 1.6% 的成本。看着不多?把成本从 0 拉到 30bp 再看:年化从 -1.83% 掉到 -2.63%、-3.42%、-4.99%、-6.54%。这里每一档成本,都在把一个本来就微弱的信号,按平方级的速度推向负值。

这条结论在私募行业里被反复验证过。量化指增产品在 2021 年之后的超额下滑,有相当一部分不是模型退化,是换手成本被交易结构吃掉了:规模变大、冲击成本上升、券源变紧、T+1 约束没变。同一套信号,管理 5 亿和管理 50 亿,是两个策略。

九、参数与重训的幻觉

我跑了一个 5 乘 4 的参数网格:训练窗口 36、48、60、84 个月和扩展窗口,组合持有 1、2、3、5 只。20 个格子里,最好的是 48 个月窗口配 1 只,年化 +5.96%;最差的是 36 个月窗口配 1 只,年化 -6.28%。

注意这两个格子是邻居。训练窗口差 12 个月,年化差 12 个百分点。这在统计上意味着什么?意味着这片网格里没有“稳健区”,只有“运气区”。如果一个参数的最优值,换一个相邻参数就崩掉,那它不是最优值,是噪音的一次采样。我在自己管的组合里吃过这个亏:2019 年我把一个策略的窗口从 48 调到 60,样本内夏普从 1.4 变成 1.9,我以为找到了更好的设定。上线三个月后,它跑出了策略史上最差的一个季度。

重训频率也是同理。很多人相信“模型要勤更新”,我的实验给的是反的:每月重训 -4.45%,每季 -3.96%,每年 -3.38%。重训越勤,越容易把最近一段噪音当成新规律。这不是说不要重训,是说重训的价值不在频率,而在“什么时候该重训”这个判断本身。

十、失效是断崖,不是斜坡

我把 130 个月按沪深300 的近 3 个月涨跌分成三种状态:涨超 8% 算上行,跌超 8% 算下行,中间算震荡。上行 75 个月,模型月均超额 -0.67%;震荡 38 个月,-0.09%;下行 17 个月,+0.35%。

这个结构很有意思:模型在上行段拖后腿,在下行段才有正贡献。原因不难猜,它学到的特征里有大量低波动、低 beta 的偏好,本质上是一个防御型的排序器。放在上涨市里,它等于慢性失血;放在下跌市里,它反而像一层薄垫子。

净值回落曲线也说明了同一点。等权基准的最大回落是 -35.39%,模型是 -55.77%。机器学习没有让曲线变浅,它只是改变了回落的形状。很多策略的“低回落”不是风控做得好,是刚好没遇上它不适应的那段市场。

最后一张图是我最常拿出来给团队看的。它画的是每年全部预测值的分布。2016 年那条线偏左,2025 年那条线明显右移。模型并不知道自己已经换了一个世界,它还在用同一套打分标准,只是打出来的分数整体位移了。这种漂移不会报警,它只会让你的排序慢慢失去意义。等你发现的时候,通常已经过了两三个季度。

十一、我把 ML 改成了否决器

2021 年之后,我不再让模型直接决定选什么。我把它放到后面,让它决定“这一次要不要做”。做法是:先用一个简单规则(12 个月动量取前 3)产生候选,再用一个分类模型预测“这一批候选这次能不能跑赢截面中位数”,低于阈值就不参与。

结果不算漂亮,但很有教育意义。不设阈值全做,年化 2.01%;阈值 0.5,年化 4.73%,但最大回落扩大到 -63.63%;阈值 0.7,年化 3.34%,参与月数只剩 29 个。校准曲线更诚实:模型说“值得做”的概率从 36% 走到 70%,实际胜率只在 46% 到 56% 之间晃,几乎没有单调关系。

所以我现在的用法是:不指望它提高胜率,只指望它降低参与次数。少做,是 ML 在低频领域唯一稳定的贡献。它没能力告诉你“这次一定对”,但它有能力告诉你“这次我不确定”。后者对活下来更有用。

十二、超额为什么消失了

把这个实验放回行业里看,2026 年的数字就有了解释。前 4 个月,中证500 指增平均超额 1.93%,中证1000 指增 3.24%。2026 年 5 月,百亿私募数量创下 139 家的新高,但当月量化策略超额明显收窄。同期有第三方统计,连续 7 个月保持正超额的管理人不足 14%。

这不是模型退化。模型在过去四年一直在进步,算力在涨,数据在涨,团队在涨。真正变化的是三件事。第一,独立维度在被耗尽:全市场能挖的低相关暴露就那么多,大家都挖到了同一批。第二,宽度红利在消失:从 500 扩到 1000 再扩到 3000,扩进来的标的相关性越来越高。第三,成本在上升:规模变大、交易拥挤、冲击成本上升。

我把它写成一个粗糙但好记的式子:机器学习能带来的边际,约等于独立维度数 × 标签信噪比 ÷ 换手成本。三个因子都是乘除关系,任何一项接近零,结果就接近零。这也解释了行业的产能分层:高频和日内最先被 ML 占领,因为它的独立维度多、标签干净、成本可控;低频指数增强最后才被改造,因为三项都不占优。

同一个模型,放在高频里是印钞机,放在月频宽基上是一台很贵的噪音发生器。不是模型有两副面孔,是这三个因子在两处完全不同。判断一个团队该不该重投 ML,先算这三项,比看他们的模型架构有用得多。

十三、ML 到底改变了什么

那它到底改变了什么?以我这十年的体感,是三件事,而且都不是“预测得更准”。

第一,它把研究从“找因子”变成了“造流水线”。过去一个研究员的核心竞争力是灵感,现在是一个能自动跑特征、自动做样本外检验、自动记录每一次失败的系统。灵感依然重要,但它不再稀缺。稀缺的是把灵感快速证伪的能力。

第二,它把“错误”从随机变成结构化。人做决策,错误是散落的,你会说“这次运气不好”。模型做决策,错误是有形状的,它会集中在你没有覆盖到的那类样本上,集中在你没定义过的那段标签上。这个变化听起来是坏事,其实是好事:结构化的错误可以被研究,随机的错误只能被忍受。

第三,它把行业从“英雄时代”推到了“产能时代”。一个天才研究员能带来的超额,正在被一个普通团队乘以算力所抵消。这也是超额消失的真正机制:机器学习让“发现”这件事的产能提升了十倍,于是 alpha 的半衰期缩短了十倍。它没有让市场变得更容易赚钱,它让市场变得更容易被研究透。

我常跟人说,机器学习在量化里的位置,像显微镜在生物学里的位置。显微镜没有让细胞变得更容易养,它让“看清”这件事变得便宜。看清之后,该做的功课一样都少不了。

十四、什么时候不该用

写到这里,我得给一份反向清单。以下四种情况,我现在的做法是不用机器学习,或者只用它做否决。

一,标的池的有效维度低于 5。这时候模型没有东西可学,你得到的只会是一个把噪音包装得很精致的排序器。先扩维度,再谈模型。

二,标签的持有期和调仓频率不匹配。这是我这篇文章里最贵的一课。用 1 个月的标签训练,却指望它指导一年的判断,或者反过来,都是在给市场送钱。

三,双边换手成本超过信号的边际。先把成本算到 30bp 再回看一遍,很多策略在这一步就死了,不用等到上线。

四,样本内 IC 显著高于样本外,且团队没有能力解释这个差距。解释不了,就意味着你无法判断它下一次什么时候失效。

结语

这篇写完,我把标题从“机器学习如何重塑量化”改成了现在这个。不是我悲观,是我觉得诚实的结论更有用。机器学习确实改变了这个行业,只是它改变的地方,和宣传里说的不一样。

它没有让我们更会预测。它让我们更快知道自己不会预测。而这两件事,在长期里,后者值钱得多。

至于那 25 张图,它们证明的不是“机器学习没用”,而是“机器学习的用处有边界,而边界的位置可以被算出来”。我倾向于每个做量化的人都自己算一遍,用自己的标的池、自己的标签、自己的成本。算完你会对很多漂亮的东西失去兴趣,这大概是件好事。

数据会说话,但它只说自己被允许说的那部分。剩下那部分,得靠人去问。

说明:本文所有图表均由公开指数行情数据在本地计算生成,样本区间为 2016 年 1 月至 2026 年 9 月,共 130 个月;模型训练采用严格滚动扩展窗口,样本外预测不使用任何未来信息;组合成本按单边 10 个基点计提,成本敏感性部分单独标注。行业数据引自私募排排网、财联社及公开媒体报道,仅用于说明行业结构变化。

本文为量化研究方法论探讨,所涉图表与数据均为历史数据的统计结果,不代表对未来任何情形的判断。文中不涉及任何具体标的的分析与推介,不构成任何形式的操作依据。市场有风险,决策需独立。

兄弟号也在写同一件事的不同侧面:真龙现身拆算法细节,麒麟财宝聊工具与平台,寻真记写量化人的思维方式,聚宝葫芦看市井里的热点。感兴趣可以一并看看。

Python社区是高质量的Python/Django开发社区
本文地址:http://www.python88.com/topic/202689