资讯详情

资讯详情

AI因子造假识别与过拟合排查:量化策略验证全流程

最近社群里的画风变得很快。以前大家问的是“这个策略回测怎么样”现在直接变成“我用AI批量生成了几十个因子回测年化百分之两三百能不能直接用”。老实说看到这类问题我第一反应不是兴奋而是先把放大镜找出来。AI批量生成因子和策略这件事本质上把“生产端”变成了无限火力但“质检端”却常常是零。判断AI生成的因子和策略是否造假、是否过拟合已经不是可选项而是这个阶段做量化交易的核心生存技能。我写这个系列到第四十九篇前面聊过回测框架、交易成本、资金管理唯独没有专门聊过“怎么审一个AI策略”。今天补上。这篇不打算给你什么花哨的指标公式而是把我在实际核查AI因子时用的那套流程完整拆开造假有哪些常见马甲、过拟合怎么在回测里伪装成稳健、拿到一个AI策略后应该按什么顺序检查。零基础也能跟上但如果你已经写过几年策略里面的排查思路同样值得过一遍。1. 为什么AI生成的因子特别容易出问题AI生成因子的逻辑本质是在一个巨大的搜索空间里找“统计上显著”的模式。这个能力既是优点也是麻烦的来源。你得先理解麻烦在哪才会对接下来要讲的造假和过拟合有切身体感。1.1 生成成本归零带来的数量幻觉以前人工挖因子一个人一个月能认真打磨三五个每个都反复验证过逻辑。AI挖因子几分钟给你吐几十上百个回测结果一个比一个漂亮。很多人拿到手就飘了这么多策略总有几个能赚钱吧问题恰恰出在这。当你同时测试几百上千个因子时概率法则就开始跟你开玩笑了。我们做个简单估算假设某个市场上一个纯随机噪声因子在单次回测中有5%的概率看起来“显著有效”这已经算保守了。那你测试200个纯噪声因子预期就会有大约10个因子通过各种显著性检验回测曲线漂亮得像精心设计的一样。你以为是挖到金矿其实只是运气在大样本下的必然显现。这就是所谓的数据挖掘偏误。人工挖因子时样本量小不小心撞上显著的概率低AI挖因子时假设检验被重复成百上千次几乎必然会出现一批“假阳性”。数量幻觉的可怕之处在于它让你误以为“挖得多希望大”实际上挖得越多需要修正的置信度门槛就越高。1.2 AI没有交易常识只有统计相关性另一个核心问题是AI模型在生成因子时脑子里其实没有“交易”这回事。它不知道什么是涨跌停、什么是停牌、什么是集合竞价也不理解为什么高换手率在实盘里会带来严重的冲击成本。它只知道某个特征序列和历史收益率之间存在相关性。相关性并不等于因果更不等于可交易的逻辑。我见过AI生成的因子里有一种用“个股过去5个交易日中名称中含某个行业关键词的股票的收益率均值”作为因子。在特定时间段内它回测时表现极好因为那段时间该行业正好有题材炒作。但把时间轴拉长这因子完全不稳定。AI不在乎这些它只是从数据里挖到了一个短暂成立的相关性。这引出一个重要结论AI生成的因子只解决了“找规律”这一步而“规律是否可交易、为何有效、何时失效”这些问题AI一概不负责。如果人也不负责那这个策略就是个没有地基的房子。所以我经常说拿到AI策略先别急着看曲线先让它解释这个因子背后的交易逻辑。如果解释不了大概率是统计噪声或者数据陷阱。1.3 核查成本远高于生成成本这是不对等的博弈AI生成一个策略可能只要30秒但你完整核查这个策略可能要三天。这个成本不对称导致很多人偷懒跳过质检。跳过质检最直接的后果就是把一个隐藏着未来函数或数据泄漏的策略直接推进实盘。更麻烦的是AI生成过程本身是黑盒。人可以通过有限次数生成大量策略但很难从生成过程本身保证质量。这就像你请了一个每小时写100份简历的求职者简历上的项目经历看起来都很唬人但每份简历都可能是拼凑和夸大。你雇人之前总要背调一下吧量化策略比简历更需要背调因为它用的不是你的钱是系统的钱。我个人的态度是AI生成因子完全可以用来做线索和灵感但在它通过完整的验证流程之前都不算“策略”只算“素材”。下面这些判断方法就是把素材变成合格策略的质检工序。2. 造假因子的四种马甲先学会看病历再看病“造假”这个词听起来像是故意为之但实际工作中绝大多数数据问题不是AI故意骗你而是它的代码生成逻辑里藏着漏洞。我把常见的造假分为四类数据泄漏、未来函数、幸存者偏差、伪逻辑因子。这四种问题的本质都是“信息被偷渡了”只是偷渡方式各不相同。2.1 数据泄漏训练集和测试集的边界被污染数据泄漏是AI因子里最常见的造假形式没有之一。它的核心特征是你在训练模型或计算因子时使用了本不该在那个时间点知道的信息。最常见的泄漏渠道有三个。第一特征预处理时用了全样本统计量比如你先对全部数据做标准化再切训练集和测试集那测试集已经被训练集的数据信息污染了回测结果必然偏乐观。第二用未来数据生成特征比如用“下一周收益率”来训练模型但在特征中也包含了一些未来区间的计算值等于让模型参考答案写作业。第三样本重叠训练期和测试期有交叠模型“见过”的行情在测试里又出现了一次。判断数据泄漏有个非常简单的方法把因子值的时间戳和标签未来收益率的时间戳画在一条时间轴上看因子生效的最晚时点是否早于标签的起点。如果因子在t日已经包含了t1日的信息哪怕只有一点点回测结果都会被系统性抬高。AI生成代码时尤其容易在这类时间对齐操作上犯错因为它经常把reset_index和shift用得很爽但没人检查对齐之后错位了多少。2.2 未来函数看起来代码没问题但成交价和信号不同步未来函数和数据泄漏的差别在于数据泄漏通常发生在训练和标签层面未来函数通常发生在交易执行层面。它指的是策略在回测中使用了“当时无法得知”的信息最典型的就是信号计算和成交价使用了同一根K线的收盘价。比如一个AI写出的日内策略用当日收盘价计算信号然后假设以当日收盘价成交次日卖出。这在回测软件里看起来很正常但实盘中你按收盘价成交需要提前下单等你看到收盘价时下单成交的已经是下一根K线的价格了。典型的表现就是回测中年化收益很高但每次成交价都恰好比最优价差一点点。另一个隐蔽的未来函数是用shift(-1)把未来数据拉回来。AI在写pandas代码时特别喜欢用负向位移因为这样代码看起来很干净。但没有严格的时间戳校验shift(-1)很容易就变成“拿明天的数据算今天的信号”。识别方法很简单在关键信号列上打印几行数据人工检查t日信号对应的t1日收益率如果信号里包含t1日的任何价格信息直接判死刑。2.3 幸存者偏差股票池本身就是被选过的幸存者偏差属于“数据层面静悄悄的造假”。AI在生成因子时如果拿到的股票池只包含今天还在上市交易的股票那么历史上那些退市的、被ST的股票就从头到尾不在样本里。这意味着模型只学习了“活下来”的股票特征天然会偏好那些后来大涨的公司。举例说明。假设你在2015年用AI挖了一个“小市值因子”只选了当时存活的股票做测试这个因子回测收益会非常好——因为退市的股票已经被剔除剩下的都是被爆炒过的看起来小市值总能超额收益。但如果你把2015年所有股票包括2016、2017年退市的都放进去这个小市值因子的收益会大幅缩水因为很多退市股票恰恰是小市值。解决幸存者偏差的方法不复杂但要花点功夫使用point-in-time数据也就是每一期只用当时实际存在的股票池。国内很多免费数据源不提供这种历史快照需要自己定期备份。我通常会至少准备一套“带退市股票”的数据做交叉验证考察同一AI因子在含退市样本和不含退市样本下的表现差异。如果差异巨大这个因子基本不能信。2.4 伪逻辑因子相关性被包装成因果性第四种是比较“软性”的造假代码没问题数据没问题但逻辑站不住脚。AI经常会生成一些在统计上显著、但没有任何交易逻辑支撑的因子我把它们叫“伪逻辑因子”。举个例子。某段时间AI可能发现一个规律股票代码尾号为8的股票月平均收益率偏高。如果在回测期内恰好有几次并购重组发生在代码尾号为8的公司上这个因子在数据里就会表现出收益增强。但它的底层驱动其实是那些公司自身的重组事件而不是代码尾号为8这件事。AI不懂这些它只看到相关。判断伪逻辑因子的一个直接方法是做时段稳定性测试把同样因子在不同市场风格下分别回测比如2017年大盘蓝筹行情、2021年新能源行情、2023年AI行情。如果因子只在一类行情里有效在其他时段完全失效那它大概率只是某段行情的投影。真正有逻辑的因子即使收益衰减也很少会从一个极端直接翻到另一个极端。提示不要要求AI因子在每个时段都赚大钱那不现实。但如果某因子只在某一段特定行情里爆发而你正好用那一段行情来做回测那它就是在假装优秀。3. 过拟合的解剖从样本内到样本外的“第五次说谎”如果说造假是“数据在说谎”那过拟合就是“统计在说谎”。造假还分善意恶意过拟合则完全是无意识的欺骗它比造假更难识别因为回测曲线不会骗你——骗你的是你对这条曲线的解释。3.1 过拟合的本质记住行情而不是理解行情过拟合的本质是模型把训练数据里的噪声当成了规律。用大白话说模型不是学会了“什么情况下股票会涨”而是背下了“过去哪几天股票涨了”。AI生成策略时模型复杂度高、参数多、搜索空间大天然容易走向过拟合。拿深度学习模型举例。一个只有两三个参数的小模型想记住复杂历史走势很难所以它只能学到粗糙规律泛化能力反而强。而AI搜索过程中可能会自动尝试几百组参数组合最终挑出在历史上表现最好的那一组。这组参数可能只是对过去几段特定行情做了深度记忆一旦行情节奏切换立刻失效。这里有个方便判断的经验法则如果策略参数有30个以上训练数据只有几百个交易日那每个参数平均只有十几个样本点来支撑过拟合几乎是必然的。不要相信“参数多但表现依然很好”的回测参数越多样本内表现好就越不值得惊讶。3.2 参数敏感性测试戳破“完美参数”的伪装识别过拟合最直接的工具不是看样本外收益而是参数敏感性测试。原理很简单一个真正有效的策略在参数小幅偏离最优值时表现应当相对平滑而过拟合策略的参数就像站在刀刃上稍微偏一点就崩盘。操作上选定策略的核心参数比如均线周期的长短、RSI的阈值、持仓周期等在最优参数基础上上下浮动10%、20%、30%分别记录回测的收益、最大回撤和夏普比率。如果收益率呈现悬崖式崩塌比如最优参数年化50%参数变化5%后年化变成-10%那这个参数就是过拟合出来的伪参数没有任何可靠性。我自己一般会把结果整理成表格来观察参数偏移幅度年化收益最大回撤夏普比率结论最优参数52.3%18.6%1.62基准-10%44.1%20.3%1.31可接受-20%25.7%28.9%0.87明显衰减10%40.8%21.1%1.18可接受20%-8.3%35.7%-0.24失效如果只有最优参数附近表现好上下浮动20%就亏损那这个策略基本是废的。真正值得实盘的策略参数变化20%-30%后收益会衰减但不会直接崩溃。3.3 交叉验证的量化陷阱时间序列不能随机切很多人拿到AI策略后会做交叉验证但直接用机器学习里的K-Fold随机切分来做时间序列数据本身就是个大坑。K-Fold随机切分假设样本之间相互独立但股票数据是强序列相关的今天的价格和明天的价格高度相关。随机切分会把未来数据混到训练集里模型在训练时已经偷看到了未来一段行情测试结果自然虚高。正确做法是使用时间序列交叉验证比如Expanding Window不断扩展训练窗口或Rolling Window滚动窗口。每次训练时只用过去的数据测试时只用未来的数据保证信息严格单向流动。我建议在验证AI因子时至少做一次“训练集截止到2020年、测试集2021-2024年”的切分测试。如果AI因子训练时是2023年才发布的数据那你还需要特别注意因子生成时是否已经包含2023年数据的统计信息——这也是时间泄漏的常见形式。3.4 Walk-forward分析的完整操作思路比一次性切分更严格的是Walk-forward Analysis也就是滚动样本外测试。简单说就是把时间轴分成很多段每段先用前面的数据训练再对后面一段做样本外测试然后窗口向前滚动重复这个过程。我用一个简化流程来说明把2018-2024年数据按月分成训练窗口和测试窗口比如训练窗口36个月测试窗口6个月。从2018-2020年训练模型在2021年上半年测试。窗口向前滚动6个月变成2018年6月-2021年6月训练在2021年下半年测试。不断重复直到覆盖完所有数据。这样会得到一系列连续样本外区间的收益记录。如果这些区间的收益整体为正且大多数区间收益与样本内同级别允许一定衰减那这个策略才算初步扛过了过拟合审查。如果只有一两个区间贡献了全部收益其他区间都在亏损那就是典型的靠运气吃饭不能要。提示样本外收益衰减多少算正常按照我的经验样本外相对样本内衰减20%-30%是正常的毕竟是不同时间段行情总有差异。但如果衰减超过50%那基本可以断定原来的“优秀”有一大半来自过拟合。4. 一套可以落地的验证流程从拿到因子到实盘判断造假和过拟合不应该靠某一个指标而应该走一套完整的质检流水线。下面这套流程是我每次拿到AI生成的因子后都会执行的标准步骤顺序很重要每一步都比上一步更耗时间但也更接近实盘真相。4.1 第一步静态逻辑审查先看代码再看曲线无论AI把回测曲线吹得多漂亮拿到的第一件事永远是打开代码看逻辑不是看净值曲线。有经验的策略研究员都明白曲线是可以被各种手段美化出来的但代码逻辑里的问题一定会在某个细节里暴露。静态审查重点看三个方面。第一数据对齐因子值计算时是否使用了shift(-1)、iloc[i1]等未来索引是否用了未来区间的全局统计量做标准化。第二标签构造训练标签是否是“未来N日收益”且因子计算的最晚时间点是否早于标签起始点。第三成交假设回测里信号价与成交价是否在同一根K线上是否忽略了涨跌停无法成交的情况是否假设了无限流动性。这一步不需要跑任何代码纯靠读代码就能筛掉一大批问题因子。如果AI生成的代码你读不懂那就先让它拆解成最小逻辑单元每一项都要给你讲明白。讲不明白的默认有问题。4.2 第二步极端场景样本外测试专挑市场不高兴的时候测逻辑审查通过后很多AI因子在正常样本外测试也能看但一到极端行情就原形毕露。所以我在第二步会专门把因子丢到几个“不愉快的行情切片”里做测试。怎么切时间点有点讲究。尽量选择包含大幅下跌、流动性枯竭、风格剧烈切换的时段。国内市场上可以参考几个典型区间2015年下半年股灾和流动性危机、2016年初熔断、2018年全年单边下行、2020年疫情冲击、2024年初小微盘流动性危机。把AI因子在这些区间内单独回测观察它是否出现极端回撤或收益崩塌。真正有逻辑的因子在极端行情下会受伤但不会莫名其妙地出现反逻辑的收益来源。比如一个“低波动”因子在2024年初小微盘崩盘时回撤大很正常因为小盘低波动股票正是流动性危机的重灾区。但一个“动量”因子如果在这种行情里反而暴涨那就要怀疑它是不是在做空波动率——这种风险收益特征在回测里看着爽实盘里遇到尾部风险会直接扛不住。4.3 第三步多空对比与交易成本压力测试很多AI因子只做了单边做多的回测这掩盖了一个核心问题它的超额收益到底来自选股能力还是来自市场整体上涨区分方法就是做多空对比。具体操作是把AI因子分为多头组合因子值最高的一组和空头组合因子值最低的一组分别回测。然后看三样东西多头收益是否明显跑赢基准、空头收益是否明显跑输基准、多空价差曲线是否平滑。如果多头和空头差不多那说明因子只是Beta的镜像没有真正的Alpha。如果多头收益高但空头不跌因子可能只是在暴露风格偏配而非有效选股。紧接着做交易成本压力测试。AI因子很容易在回测里隐藏过高的换手率。你把佣金调成单边万三、印花税千一、滑点成交价偏移一个最小变动价位再回测一遍。如果策略收益从年化50%掉到年化5%那它实盘基本没有可操作性。这里我额外提一点回测软件里的滑点参数设置往往偏乐观实盘里小盘股的冲击成本和延时远大于你的设置建议至少按回测滑点的两倍再做一次压力测试。4.4 第四步部署前的模拟盘与因子监控记录经过前三步仍然“活下来”的AI因子数量大概会从你最初的几十个变成两三个。这时候再进入实盘前的最后一关模拟盘记录和实时因子监控。不要急着投钱先用模拟盘跑至少一个完整月并记录因子每天的IC值。IC就是因子值与未来收益的相关系数是衡量因子预测能力的核心指标。计算方式上每天计算因子值与次日或未来N日收益的Spearman秩相关然后看均值、标准差和ICIR。回测期与模拟盘期的IC均值对比非常关键。如果模拟盘IC均值远低于回测期衰减超过30%说明因子的有效性在当下市场环境里已经大打折扣。模拟盘期间还要看因子是否出现“脏数据污染”比如停牌股没有剔除、ST股混入股票池、新股上市前几日被纳入导致价格异常。这部分没有捷径只能靠每天的日志和报表盯。个人经验是模拟盘跑满20个交易日以上且因子IC稳定为正才具备实盘小仓位的资格只跑一两周就急着上的都是赌徒心理。我还会在部署前建立一份“因子出生证”记录几个关键信息因子生成日期、训练数据截止日期、数据快照版本、参数选择过程、样本外测试区间、模拟盘启动时间。这份出生证是以后回溯策略问题的关键——等因子失效时你能知道它是在什么数据上被发现的、当时验证到了哪一步、现在偏离了多少。没有出生证的因子就像没有疫苗记录的宠物出了事你连该怀疑哪一环都不知道。5. 我踩过的坑回测曲线越漂亮越要警惕最后这部分讲几个真实的踩坑记录。这些坑我在过去几年里都切切实实踩过也为此交过学费。拿出来说是希望你在AI因子这条路上少走我走过的弯路。5.1 年化500%的因子三个星期后归零那是2022年底一个朋友拿了个AI生成的日内策略给我看回测年化超过500%最大回撤不到5%。曲线几乎90度向上堪称完美。我静态审查代码时发现策略在t日收盘时产生信号同时就以t日收盘价成交没有考虑信号产生和成交之间的时滞。朋友觉得就差那么几个点无所谓结果实盘三个星期不仅没有500%的收益反而亏了十几个点。问题恰恰出在那个“差几个点”上。高频或日内策略对成交价格的敏感性是数学级的——信号价和成交价的偏差只要超过0.5%高频策略的收益就很容易被吃掉。回测里看起来只差几个最小变动价位实盘里可能是完全不同的世界。5.2 换手率被低估的代价另一个AI因子回测换手率显示月均换手在30%左右算上佣金和滑点后还有不错的收益。上线后我发现实际成交过程中的冲击成本远高于回测假设。原因是AI因子选出来的股票集中在小市值范围这些股票流动性本身就很差每笔成交都会推动价格向不利方向移动。回测软件里设的固定滑点忽略了“策略在买的时候别人也在买”的反馈效应。这事给我的教训是回测里的换手率需要叠加一个“流动性系数”来看。如果因子持仓集中在成交额排名后20%的股票无论AI把逻辑包装得多完美我都建议直接降低仓位上限或者干脆不用。策略的账面收益永远不等于实际收益中间的差额就叫交易摩擦AI不告诉你摩擦多大但你的账户会把真实的摩擦给你看。5.3 关于“AI自动挖因子”的个人建议经历这些之后我现在的态度很明确AI挖因子可以但要把AI当作一个“能力极强、经验为零、毫无羞耻心”的实习生。它可以在几小时内完成一个人几周的工作量但它完全不知道什么是合理的什么是瞎编的。如果你不设质检流程它就会源源不断地给你制造“听起来很美”的垃圾。给自己定两条铁律。第一条所有AI因子在通过完整质检前一律不算策略只算素材。第二条如果一个AI因子的回测收益超过你熟悉的同类人工因子两倍以上请默认它有问题先去证明它有问题再考虑它是不是天才之作。好消息是证明它有问题通常比证明它有效快得多。落实到日常操作我习惯把AI生成的因子分门别类放进一个“因子库”目录后备注生成日期和数据快照版本每次只挑最有机会的1到2个走完整验证流程绝不批量上马。宁可错过十个好因子也不要踩中一个坏因子——在量化这个领域踩中一个坏因子的成本往往需要几十个好因子才能弥补回来。
觉得有用,分享给同行:

为您的企业打造数字门面

稳重轻奢商务风格,端正雅致视觉,长效耐看不易过时。

立即咨询 →