时间序列:连明天中午吃啥都猜不准,还想预测股价?

📅 2026/7/29 4:42:36
时间序列:连明天中午吃啥都猜不准,还想预测股价?
去年有个创业的朋友找我喝茶神神秘秘地掏出手机给我看一个App。他说他用深度学习预测A股回测年化收益百分之四十准备辞职全职炒股。我看了他的模型代码LSTM叠了三层输入特征包括开盘价、收盘价、成交量、MACD、KDJ、RSI还有他手动标注的“重大利好事件”哑变量。训练集从2015年到2020年测试集是2021年上半年预测准确率高得离谱。我只问了他一个问题“你的训练集和测试集是怎么划分的”他说“随机抽样啊百分之八十训练百分之二十测试。”我当时差点把茶喷出来。随机抽样。他把五年的时间序列数据打散了随机抽百分之八十训练剩下百分之二十测试。这意味着什么意味着模型在训练的时候已经看过了2019年的数据然后去预测2017年的股价。这不是预测这是作弊。时间序列的因果箭头只能从过去指向未来你用未来的信息去预测过去模型当然学得会。在真实场景里你永远只能用今天之前的数据预测明天之后的事情。后来他按时间顺序重新划分数据集前四年训练最后一年测试。准确率直接腰斩年化收益变成了负数。他没辞职App也卸载了。这个故事我讲过很多遍因为它是时间序列预测里最常见也最致命的错误你以为你在预测未来其实你只是在背诵历史。一、时序问题里的时间陷阱远不止随机抽样时间序列数据是带记忆的这个记忆会让一切看起来更美好也让一切变得更脆弱。我做过一个App日活预测的项目。一开始用ARIMA拟合效果很好残差白噪声检验也通过了看着挺美。上线跑了三个月预测准确率越来越差。查了一个星期才发现问题我的模型训练数据里包含了一段疫情期间的居家隔离期那几个月日活暴涨了百分之六十。模型学到的是一个巨大的人造脉冲它把这个脉冲当成了某种周期性模式。疫情结束后模型还在试图预测下一个类似的脉冲会出现每一次预测都偏高。这种“异常事件污染训练集”的问题在时间序列里简直无解。你没法把疫情数据当成异常值删掉因为它代表了真实发生过的事情而且影响了之后很长时间的趋势。但你保留它它会把模型的参数估计拉偏。我最后的折中方案是在训练集里加入一个虚拟变量标注“是否处于特殊事件期间”让模型把这部分变异归因到虚拟变量上而不是学进趋势和季节成分里。效果好了不少但远远称不上完美。还有一种更隐蔽的时间陷阱数据本身的生成机制在变化。你做一个电商平台GMV预测三年前的数据和三后的数据背后的用户结构、品类分布、促销策略、竞对格局全变了。你拿三年前的数据训练模型等于假设数据生成过程是平稳的。这个假设在现实里几乎从来不成立。老数据不仅不能帮助预测还会拖后腿。我现在的习惯是训练数据尽量不超过两年的窗口越近的数据权重越高必要时直接上遗忘因子让模型逐渐淡忘远古的记忆。二、非平稳性教科书给你讲明白了但真实数据从不配合时间序列预测的第一课平稳性。单位根检验差分ACF图PACF图一个不能少。这个流程我在学校考过满分在工作中被虐得满地找牙。教科书上的例子差分一次趋势就没了数据漂漂亮亮变平稳。现实里你拿日活数据做一阶差分周期性还在季节性还在方差还跟着水平一起涨。再做一次季节性差分十二阶差分之后序列是平稳了但你也快不认识它了——原始的业务含义被差分操作洗得一干二净预测出来的差分值再还原回去误差会被层层放大最后给出一个令人啼笑皆非的置信区间明天日活预测值一百万下界五十万上界两百万。运营部门拿着这个区间问我“所以你的意思是明天用户可能会来也可能不来”我后来慢慢放弃了对完美平稳性的执念。真实业务场景里与其花大量精力把非平稳序列强行扭成平稳不如直接用能处理非平稳特性的模型。Prophet对趋势和季节性的分解很鲁棒LightGBM直接上滞后特征和时间特征也不怎么怕非平稳甚至XGBoost加足够的滞后阶数也能硬扛。这些模型的预测能力不一定比严谨的ARIMA差而且省心太多了。当然省心是有代价的——放弃了统计推断的严谨性你没法优雅地给出预测区间和显著性检验。但在老板只需要一个“大概多少”的数字来做预算的时候优雅不值钱。三、外部变量你以为找到了圣杯其实是打开了潘多拉魔盒做时序预测的人都有一个不断膨胀的特征表。先加滞后值一阶二阶三阶再加滑动窗口统计量过去七天均值过去三十天标准差然后加日历特征星期几是不是周末是不是月初是不是节假日。模型效果依然不够好你开始引入外部变量天气、竞品动态、广告投放金额、搜索指数、社交媒体声量。外部变量一加进去模型精度确实上去了。但在预测场景下你用外部变量就陷入了逻辑循环你要预测明天的销量你需要知道明天的广告投放金额——但明天的投放金额还没确定呢。你要预测下周的日活你需要下周的天气数据——但气象台的七天预报准确率比你想象的感人得多。你用未来的不确定去预测未来的不确定不确定性不是变小了是叠加了。更现实的做法是在预测时间点之前能拿到的所有信息才叫特征。明天的天气你不确定但你可以在今天拿到“明天天气预报的气温预测值”这个预测值本身就是可用的特征即使它不准确它代表了你做决策时实际掌握的信息。明天的广告投放金额没定但你可以用“预算计划中的投放金额”作为特征上线之后再根据实际投放做误差修正。预测模型不是要预知未来而是要模拟“在当下这个时点人拿着所有已知信息能做出的最合理的判断”。这个定位一旦想清楚很多外部变量的使用困境就迎刃而解了。四、评估指标越低越好但越低可能越糟时间序列预测最常用MAPE平均绝对百分比误差。MAPE好用直观能跨量级比较。但它有两个道德败坏的问题。第一真实值是零的时候MAPE直接爆炸分母为零。日销量在某些品类某些天确实可能是零你没法算MAPE只能跳过或者用SMAPE但SMAPE在真实值和预测值都接近零的时候也不稳定。第二MAPE对低估的惩罚比高估轻。真实值一百你预测一百五误差百分之五十真实值一百你预测五十误差也是百分之五十。看起来对称对吧实际不是。供应链场景里你低估了销量导致缺货损失远大于高估导致的库存积压。用MAPE当优化目标模型会倾向于给出保守的低预测因为这样优化更快但业务伤害更大。我后来在很多项目里弃用了MAPE改用自定义的加权损失函数。高估和低估的惩罚系数不一样惩罚系数由业务部门根据实际成本来定。比如一个缺货成本是积压成本三倍的场景损失函数就设成低估误差权重三高估误差权重一。这个改动让模型的业务价值直接上了个台阶预测数量虽然没有更精准但预测错误的代价大幅下降了。还有一个几乎没人提但很要命的点不同时间点的预测误差业务代价也不一样。你在大促当天的预测误差和平日一个普通周三的预测误差能相提并论吗大促日备货翻车全年奖金泡汤。我现在的评估体系里会给关键日期设样本权重双十一、618、黑色星期五这些大节点的误差在模型优化时被反复强调平时的小误差允许稍微放飞一下。这比任何花哨的模型升级都更直接有效。五、预测的意义有时候不是预测本身做了这么多年时间序列我越来越觉得预测的最大价值不在于给出那个数字而在于让你理解系统的动态规律。你花了两个月搭了一个精确度还可以的销量预测模型这个过程中你搞清楚了销售的季节性模式、促销的衰减效应、竞对活动的冲击时滞。这些东西写进文档里业务部门拿去排生产计划、定安全库存、做预算分配比模型吐出来的那一个数字有用得多。模型会过时会漂移会被突发事件打脸但你对业务节奏的理解是实打实沉淀下来的资产。而且很多时候业务方要的不是精确预测而是一个合理的范围加上应对方案。你告诉他们下个月销量大概率在一百万到一百二十万之间如果低于一百万我们启动什么预案如果高于一百二十万我们怎么调配资源。这个比咬死“下个月销量一百零八万三千二百”有用一百倍。精确到个位数的预测反而会给人一种虚假的安全感让人放弃准备应急预案。当真实值偏离预测的时候所有人手忙脚乱。我现在汇报预测结果的时候一定会花至少一半的时间讲不确定性。这个预测基于什么假设哪些假设最容易翻车翻车了数值会往哪个方向偏我们能提前观察哪些信号来判断假设还成不成立这些问题回答清楚了即使预测数字本身错了决策者心里也有底知道接下来该怎么调。说到底时间序列预测是一门在不确定中寻找确定边界的活计。你永远猜不准明天中午吃啥但你知道大概率不会是龙虾。你永远猜不准明天股价涨跌但你知道在财报发布日和美联储议息日波动会更大。把能确定的边界画清楚把不确定的部分诚实地标注出来剩下的交给现实去演绎。至于那些宣称自己模型能精准预测股价的要么在卖课要么还没睡醒。