ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

时序预测模型为何在假装理解数据?LSTM、Transformer与LightGBM的实战诊断

时序预测模型为何在假装理解数据?LSTM、Transformer与LightGBM的实战诊断 1. 时序预测的“皇帝新衣”为什么你的模型在假装理解数据做时序预测这行的朋友大概都有过这种经历辛辛苦苦搭了个LSTM或者Transformer在训练集上Loss降得漂漂亮亮验证集看着也还行一上测试集或者一到真实业务场景里预测结果就开始“放飞自我”。你以为是过拟合加了Dropout、调了正则化你以为是数据不够又去爬了几万条数据你以为是模型不够深把层数从2层堆到12层。折腾一圈下来效果该烂还是烂。问题出在哪我踩了几年坑之后才慢慢想明白一件事很多时序预测模型其实在“假装”理解你的数据。它们看起来在学习时序规律实际上只是在记忆训练集里的统计巧合或者更直白地说在“抄近道”。你给它一段历史价格它学会的是“明天大概率和今天差不多”而不是“明天为什么会和今天不一样”。这种“假装理解”在金融时序预测里尤其致命因为金融数据的信噪比极低模型很容易把噪声当信号把巧合当规律。这篇文章我想聊的就是这个事。不是要否定时序预测的价值而是想把这层窗户纸捅破把“模型到底在学什么”这个问题拆开来看。我会结合滑动窗口滤波模型、LightGBM回归、LSTM、Transformer这些常见方案讲讲它们各自在什么情况下会“假装理解”以及怎么用一些实操手段去验证和缓解。适合已经跑过几个时序项目、但总觉得效果“差一口气”的朋友也适合刚入门想少走弯路的同学。2. 拆解“假装理解”模型到底在学什么2.1 时序预测的本质从历史到未来的映射先把问题简化一下。时序预测说到底就是找一个函数f让y_{t1} f(y_t, y_{t-1}, ..., y_{t-n})。这个函数可以简单到“昨天等于今天”也可以复杂到几百层神经网络。但不管多复杂模型能学到的信息只有两个来源一是输入窗口里的历史值二是训练过程中见过的模式。问题在于历史值里包含的信息量是有限的。如果数据本身是白噪声那任何模型都只能学到“均值回归”预测结果就是一条水平线。如果数据有强趋势模型学会的就是“延续趋势”。如果数据有周期性模型学会的就是“重复周期”。这些都不是真正的“理解”而是统计规律的拟合。我见过太多项目数据预处理做完之后序列已经变得非常平滑然后模型在平滑后的序列上表现很好但一还原到原始尺度就崩了。这就是典型的“假装理解”——模型学的是预处理后的规律而不是原始数据的生成机制。2.2 滑动窗口滤波平滑背后的信息损失滑动窗口滤波是时序预处理里最常用的手段之一。移动平均、指数平滑、Savitzky-Golay滤波本质上都是在做一件事用窗口内的局部统计量代替原始值。这么做的好处是降噪坏处是把高频信息抹掉了。举个具体的例子。假设你有一条日频的股票收盘价序列做5日移动平均之后序列变得很平滑趋势一目了然。然后你拿这个平滑序列去训练LightGBM回归模型特征就是前5天的平滑值标签是第6天的平滑值。模型很快就能学到“第6天约等于前5天的平均”因为平滑后的序列自相关性极强。但问题是这个规律在原始序列上根本不成立——原始序列的日间波动可能完全被平滑掉了。更麻烦的是滑动窗口滤波会引入相位延迟。窗口越大延迟越明显。如果你用滤波后的序列做预测再还原到原始时间轴会发现预测值总是“慢半拍”。这在金融时序预测里是致命的因为价格转折点往往就在那半拍里。注意滑动窗口滤波不是不能用但一定要清楚它抹掉了什么信息。如果业务场景对转折点敏感滤波窗口要尽量小或者干脆不用滤波改用对异常值更鲁棒的特征工程。2.3 金融时序的特殊性低信噪比与非平稳性金融时序预测是时序预测里最难啃的骨头之一。原因有两个一是信噪比极低价格波动里大部分是噪声真正的信号可能只占5%不到二是非平稳性数据的统计分布随时间变化今天有效的规律明天可能就失效了。在这种数据上模型特别容易“假装理解”。比如用LSTM预测股价模型很快会学到“预测值接近当前值”这个策略因为这样在大多数时候Loss都很低。但这不是预测这是复制。你拿这个模型去做交易它会在趋势启动时完全跟不上在震荡市里反复被打脸。我试过用LightGBM做金融时序预测特征里加了大量技术指标MACD、RSI、布林带等标签是未来5日收益率。模型在训练集上AUC能到0.7但样本外一测就掉到0.5左右。后来分析特征重要性发现模型最依赖的特征是“过去5日收益率均值”而这个特征在样本外几乎没有任何预测力。这就是典型的“假装理解”——模型抓住了一个在训练集里偶然有效的特征但它在未来失效了。2.4 模型复杂度与数据量的错配还有一个常见的坑是模型复杂度和数据量不匹配。Transformer模型动辄几百万参数如果你只有几千条时序数据模型很容易过拟合。过拟合的表现不一定是训练Loss低、验证Loss高也可能是训练Loss和验证Loss都低但样本外表现一塌糊涂。后者更隐蔽因为你看Loss曲线会觉得“模型学得很好”。我见过一个案例用Longformer中文模型做金融文本情感分析然后拿情感得分作为特征去预测股价。模型在训练集上情感分类准确率90%以上但情感得分和股价的相关性在样本外几乎为零。问题不在于情感分析模型不好而在于情感和股价之间的映射关系本身就不稳定模型学到的只是训练集里的偶然相关。3. 常见时序预测方案的“假装”现场3.1 LSTM与Transformer记忆的幻觉LSTM和Transformer是时序预测里最常用的两个深度学习方案。LSTM靠门控机制记忆长期依赖Transformer靠自注意力捕捉全局关系。听起来都很美好但在实际时序任务里它们经常在“假装理解”。LSTM的问题在于它的记忆能力是有偏的。门控机制倾向于记住近期信息遗忘远期信息。如果你的时序依赖跨度很长LSTM实际上记不住。更麻烦的是LSTM对输入尺度很敏感如果序列里有异常值门控状态会被带偏导致后续预测全部失真。Transformer的问题在于自注意力机制在时序数据上容易“注意力涣散”。时序数据的相邻点之间相关性很强但Transformer的注意力是全局的它会把注意力分散到所有时间步上。结果就是模型学到的注意力权重看起来很均匀实际上没有抓住关键时间点。我试过用Transformer做电力负荷预测注意力可视化出来一看模型对过去24小时每个点的关注度都差不多这等于没关注。实操心得用LSTM或Transformer做时序预测时一定要做输入标准化而且标准化参数要用训练集的统计量不能用到验证集或测试集的信息。另外序列长度不要设得太长LSTM一般50-100步就够了Transformer可以到200步再长收益递减。3.2 LightGBM回归特征工程的陷阱LightGBM在时序预测里很受欢迎因为它训练快、对特征工程友好、可解释性强。但LightGBM有个特点它非常擅长抓住特征里的统计规律哪怕这个规律是虚假的。举个例子。你用东财股票数据API拉了一段股价数据构造了一堆特征过去N日收益率、成交量均值、换手率、MACD等。然后你用LightGBM回归预测未来5日收益率。模型训练完特征重要性排第一的是“过去5日收益率均值”。这个特征在训练集里确实和未来收益有相关性因为训练集里可能刚好有一段趋势行情。但样本外一测这个特征就失效了。问题不在于LightGBM不好而在于特征本身没有稳定的预测力。LightGBM只是忠实地反映了训练集里的统计关系它不会判断这个关系是否合理。所以用LightGBM做时序预测特征工程的质量比模型调参重要得多。3.3 滑动窗口滤波模型平滑的代价滑动窗口滤波模型严格来说不算一个独立的模型而是一种预处理预测的组合方案。常见做法是先对原始序列做移动平均或指数平滑然后在平滑序列上训练预测模型最后把预测结果还原到原始尺度。这种方案的问题在于平滑后的序列和原始序列的统计特性完全不同。平滑序列的自相关性更强、方差更小、趋势更明显。模型在平滑序列上学到的规律不一定适用于原始序列。更麻烦的是如果你用平滑序列做训练用原始序列做测试模型的表现会断崖式下跌。我试过一个方案用Savitzky-Golay滤波对股价序列做平滑窗口长度21多项式阶数3。平滑后的序列确实很漂亮趋势一目了然。然后我用LSTM在平滑序列上训练预测未来5日平滑值。训练集Loss降到0.001验证集Loss也很低。但把预测值还原到原始尺度后和真实价格的相关系数只有0.1左右。这就是平滑的代价——模型学的是平滑后的规律不是原始数据的规律。3.4 方案对比什么场景用什么方案方案适用场景容易“假装理解”的点缓解手段LSTM中短序列、非线性依赖记忆衰减、对异常值敏感输入标准化、梯度裁剪、序列长度适中Transformer长序列、全局依赖注意力涣散、过拟合位置编码、注意力正则、数据增强LightGBM特征丰富、可解释性要求高特征虚假相关、过拟合特征筛选、滚动窗口验证、正则化滑动窗口滤波强噪声、趋势提取信息损失、相位延迟小窗口、保留残差、端到端训练这张表不是绝对的但能帮你快速判断自己的方案可能在哪里出问题。核心思路是任何方案都有它的“假装”方式关键是要知道它在什么情况下会假装以及怎么验证它是不是在假装。4. 实操如何验证模型是不是在“假装理解”4.1 滚动窗口验证时间序列的交叉验证普通交叉验证在时序数据上不能用因为会引入未来信息。时序数据必须用滚动窗口验证也叫前向链式验证。具体做法是把数据按时间顺序分成K折每次用前k折训练用第k1折验证然后滑动窗口向前推进。import numpy as np from sklearn.model_selection import TimeSeriesSplit # 假设X是特征矩阵y是标签 tscv TimeSeriesSplit(n_splits5) for train_index, test_index in tscv.split(X): X_train, X_test X[train_index], X[test_index] y_train, y_test y[train_index], y[test_index] # 训练模型并评估 model.fit(X_train, y_train) score model.score(X_test, y_test) print(fFold score: {score})滚动窗口验证的关键是不能打乱数据顺序而且训练集和验证集之间要有时间间隔gap避免信息泄露。比如预测未来5日收益率训练集和验证集之间至少要隔5天。我一般会做至少5折滚动验证然后看各折得分的均值和方差。如果均值低、方差大说明模型不稳定很可能在“假装理解”。如果均值高、方差小才说明模型学到了稳定的规律。4.2 特征重要性分析模型到底在看什么对于树模型LightGBM、XGBoost特征重要性是最直接的诊断工具。如果模型最依赖的特征是“过去N日收益率均值”这种自相关特征那就要警惕了。因为这种特征在趋势行情里有效在震荡市里失效。更深入的做法是看特征重要性的稳定性。具体来说在滚动窗口验证的每一折里都输出特征重要性然后看哪些特征的重要性排名稳定。如果某个特征在某一折里排第一在另一折里排第十那这个特征很可能只是偶然有效。对于深度学习模型可以用排列重要性Permutation Importance来诊断。做法是把某个特征的值随机打乱看模型性能下降多少。下降越多说明模型越依赖这个特征。如果打乱某个特征后模型性能几乎不变说明模型根本没在用这个特征。4.3 残差分析模型没学到的部分残差分析是诊断时序模型最有效的手段之一。具体做法是把模型预测值和真实值的差残差画出来看残差有没有规律。如果残差是白噪声说明模型学到了所有可学的信息。如果残差还有自相关、趋势或周期性说明模型漏掉了某些规律。import matplotlib.pyplot as plt from statsmodels.graphics.tsaplots import plot_acf # 计算残差 residuals y_true - y_pred # 画残差自相关图 plot_acf(residuals, lags40) plt.show() # 画残差时序图 plt.plot(residuals) plt.axhline(y0, colorr, linestyle--) plt.show()如果残差自相关图显示前几阶有显著的自相关说明模型没有抓住短期依赖。如果残差时序图显示残差有趋势说明模型没有抓住趋势。如果残差有周期性说明模型没有抓住周期性。我试过一个案例用LSTM预测电力负荷残差自相关图显示滞后24小时有显著自相关。这说明模型没有学到日周期性。后来在特征里加了“昨天同一时刻的负荷值”模型性能立刻提升了一大截。4.4 样本外测试最后的照妖镜不管滚动窗口验证做得多好最终还是要看样本外测试。样本外测试的数据必须是模型完全没见过的而且时间上要晚于训练数据。我一般会留出最后20%的数据做样本外测试而且这部分数据在模型开发和调参过程中绝对不能碰。样本外测试的评估指标要和业务目标对齐。如果业务目标是预测方向就看方向准确率如果业务目标是预测幅度就看MAE或RMSE。不要只看一个指标要多个指标交叉验证。注意样本外测试只能做一次。如果你反复用样本外数据调参那它就不再是样本外了。我见过太多人把样本外数据当验证集用调来调去最后模型在样本外表现很好一上真实业务就崩了。5. 缓解“假装理解”的实操技巧5.1 数据层面让模型看到真实分布缓解“假装理解”的第一招是从数据入手。具体来说有以下几个手段第一保留原始尺度。不要过度预处理。如果一定要做平滑把平滑后的序列和原始序列都作为特征输入模型让模型自己选择用哪个。我试过在LightGBM里同时加入原始价格和平滑价格模型会自动给原始价格更高的权重因为它的预测力更强。第二加入噪声增强。在训练时给输入序列加入小幅高斯噪声可以提升模型的鲁棒性。噪声幅度一般设为序列标准差的1%-5%。这么做相当于告诉模型“输入是有噪声的不要过度依赖某个具体值。”第三用滚动统计量代替全局统计量。标准化的时候不要用全局均值和方差用滚动窗口的均值和方差。这样能更好地适应非平稳性。比如用过去60天的均值和方差来标准化当前值而不是用全样本的均值和方差。5.2 特征层面构造有物理意义的特征特征工程是缓解“假装理解”的关键。好的特征应该是有物理意义的而不是纯粹的统计巧合。比如做金融时序预测与其用“过去5日收益率均值”不如用“过去5日收益率均值的分位数”因为分位数能反映当前值在历史分布中的位置更有物理意义。另一个技巧是构造差分特征。原始价格是非平稳的但一阶差分收益率通常是平稳的。用差分特征训练模型能减少非平稳性带来的虚假相关。我一般会同时加入原始值、一阶差分、二阶差分让模型自己选择。还有一个技巧是加入外部特征。纯时序模型只看历史值信息量有限。如果能加入外部特征比如宏观经济指标、行业指数、市场情绪等模型能学到更丰富的规律。但要注意外部特征的时间对齐要做好不能用未来信息。5.3 模型层面正则化与集成模型层面的缓解手段主要是正则化和集成。正则化方面LSTM可以加Dropout和权重衰减Transformer可以加注意力Dropout和层归一化LightGBM可以加L1/L2正则和树深度限制。集成方面可以用多个不同随机种子的模型做平均或者用不同架构的模型做Stacking。我试过一个方案用5个不同随机种子的LSTM做平均预测结果的方差比单个模型小很多样本外表现也更稳定。这就是集成的力量——单个模型可能在“假装理解”但多个模型的平均能抵消掉一部分虚假规律。另一个技巧是早停Early Stopping。在验证集Loss不再下降时停止训练能有效防止过拟合。但要注意验证集必须是时序上晚于训练集的数据不能用随机划分的验证集。5.4 评估层面多指标交叉验证评估层面最重要的是不要只看一个指标。我一般会同时看以下几个指标MAE/RMSE衡量预测幅度误差方向准确率衡量预测方向是否正确IC/IR衡量预测值和真实值的秩相关夏普比率如果用于交易看风险调整后收益如果模型在MAE上表现很好但方向准确率只有50%说明模型只是在“抄近道”没有真正理解数据。如果IC很高但IR很低说明预测不稳定时好时坏。实操心得我一般会画一张“预测值vs真实值”的散点图。如果散点集中在45度线附近说明模型预测准确。如果散点分布很散或者有明显的偏差说明模型有问题。这张图比任何指标都直观。6. 常见问题与排查技巧实录6.1 模型在训练集上表现很好样本外一塌糊涂这是最典型的问题。原因通常是过拟合但过拟合的原因可能有很多种。排查思路如下可能原因排查方法解决方案数据泄露检查特征里有没有未来信息严格按时间划分加gap过拟合看训练Loss和验证Loss的差距加正则化、减模型复杂度非平稳性看训练集和测试集的分布差异用滚动标准化、差分特征虚假相关看特征重要性的稳定性特征筛选、滚动验证我遇到过一个案例模型在训练集上R²0.95样本外R²-0.1。排查后发现特征里有一个“未来5日收益率均值”这个特征在训练集里和标签高度相关但在样本外完全无效。去掉这个特征后样本外R²提升到0.3。6.2 预测值总是滞后于真实值这是时序预测的经典问题叫“相位延迟”。原因通常是模型学到了“预测值接近当前值”这个策略。解决方案有以下几个第一用差分标签。不要直接预测未来值预测未来值和当前值的差。这样模型必须学到变化方向而不是简单复制当前值。第二加入方向损失。在Loss函数里加入方向惩罚项如果预测方向和真实方向相反就加大惩罚。这样模型会更关注方向而不是幅度。第三用分类代替回归。把预测问题转化为分类问题预测未来是涨还是跌。这样模型不会“抄近道”因为分类问题没有“接近当前值”这个选项。我试过用LightGBM做分类预测未来5日涨跌方向准确率能到55%左右。虽然不高但比回归模型的50%好多了。而且分类模型的预测值没有滞后问题因为它输出的是概率不是价格。6.3 模型在不同时间段表现差异很大这也是非平稳性的表现。解决方案是滚动训练。不要用全部历史数据训练一个模型而是用最近N天的数据训练然后滚动更新。N的选择要看业务场景金融数据一般用最近1-2年电力负荷可以用最近1年。滚动训练的实现方式有两种一种是每天重新训练一种是用在线学习Online Learning增量更新。前者计算量大但简单后者计算量小但需要模型支持增量更新。LightGBM支持增量训练LSTM可以用小学习率微调。我一般会用滚动训练集成的方式用最近1年数据训练5个不同随机种子的模型然后平均。这样既能适应非平稳性又能保持稳定性。6.4 特征重要性排名不稳定这说明模型没有学到稳定的规律。解决方案是特征筛选。具体做法是在滚动窗口验证的每一折里都输出特征重要性然后只保留在多数折里都排前20%的特征。这样能过滤掉偶然有效的特征。另一个技巧是用SHAP值代替特征重要性。SHAP值能给出每个特征对每个预测的贡献比全局特征重要性更细粒度。如果某个特征的SHAP值在不同样本间差异很大说明这个特征不稳定。import shap # 训练LightGBM模型 model lgb.LGBMRegressor() model.fit(X_train, y_train) # 计算SHAP值 explainer shap.TreeExplainer(model) shap_values explainer.shap_values(X_test) # 画SHAP摘要图 shap.summary_plot(shap_values, X_test)SHAP摘要图能直观展示每个特征对预测的影响方向和大小。如果某个特征的影响方向在不同样本间不一致说明这个特征不稳定。6.5 模型在极端行情下完全失效极端行情是时序预测的“照妖镜”。在极端行情下历史规律往往失效模型学到的规律不再适用。解决方案有以下几个第一加入极端行情样本。在训练集里加入历史极端行情数据让模型见过“世面”。但要注意极端行情样本不能太多否则模型会过度关注极端情况。第二用鲁棒损失函数。比如Huber Loss、Quantile Loss这些损失函数对异常值不敏感能减少极端行情对模型的影响。第三设置预测置信度。如果模型对某个预测的置信度很低就输出“不确定”而不是强行预测。置信度可以用预测方差、集成模型的预测分歧度来衡量。我试过用Quantile Loss训练LightGBM预测未来收益率的10%分位数和90%分位数。在极端行情下模型输出的区间会变宽提示风险增加。这个方案在实际交易里很有用能避免在极端行情下重仓。7. 一个完整的实操案例从数据到诊断7.1 数据准备与特征工程假设我们有一份日频股票数据包含开盘价、收盘价、最高价、最低价、成交量。目标是预测未来5日收益率。数据准备步骤如下import pandas as pd import numpy as np # 读取数据 df pd.read_csv(stock_data.csv, parse_dates[date]) df df.sort_values(date).reset_index(dropTrue) # 构造特征 df[return_1d] df[close].pct_change(1) df[return_5d] df[close].pct_change(5) df[volatility_5d] df[return_1d].rolling(5).std() df[volume_ma5] df[volume].rolling(5).mean() df[volume_ratio] df[volume] / df[volume_ma5] # 构造标签未来5日收益率 df[label] df[close].shift(-5) / df[close] - 1 # 去掉缺失值 df df.dropna().reset_index(dropTrue) # 划分训练集和测试集 train_size int(len(df) * 0.8) train_df df.iloc[:train_size] test_df df.iloc[train_size:]特征工程的关键是不要用未来信息。所有特征都只能用当前时刻及之前的数据计算。标签是未来5日收益率所以最后5天的数据没有标签要去掉。7.2 模型训练与滚动验证用LightGBM做滚动窗口验证import lightgbm as lgb from sklearn.model_selection import TimeSeriesSplit # 特征列 feature_cols [return_1d, return_5d, volatility_5d, volume_ma5, volume_ratio] X train_df[feature_cols].values y train_df[label].values # 滚动窗口验证 tscv TimeSeriesSplit(n_splits5) scores [] for train_idx, val_idx in tscv.split(X): X_train, X_val X[train_idx], X[val_idx] y_train, y_val y[train_idx], y[val_idx] model lgb.LGBMRegressor( n_estimators100, max_depth5, learning_rate0.05, subsample0.8, colsample_bytree0.8, reg_alpha0.1, reg_lambda0.1 ) model.fit(X_train, y_train) # 评估 from sklearn.metrics import mean_squared_error, mean_absolute_error y_pred model.predict(X_val) rmse np.sqrt(mean_squared_error(y_val, y_pred)) mae mean_absolute_error(y_val, y_pred) scores.append((rmse, mae)) print(fFold RMSE: {rmse:.4f}, MAE: {mae:.4f}) print(fAverage RMSE: {np.mean([s[0] for s in scores]):.4f}) print(fAverage MAE: {np.mean([s[1] for s in scores]):.4f})滚动窗口验证的结果能告诉你模型是否稳定。如果各折RMSE差异很大说明模型不稳定。7.3 残差分析与诊断训练完模型后做残差分析# 用全部训练数据训练最终模型 final_model lgb.LGBMRegressor( n_estimators100, max_depth5, learning_rate0.05, subsample0.8, colsample_bytree0.8, reg_alpha0.1, reg_lambda0.1 ) final_model.fit(X, y) # 在测试集上预测 X_test test_df[feature_cols].values y_test test_df[label].values y_pred_test final_model.predict(X_test) # 残差分析 residuals y_test - y_pred_test print(fTest RMSE: {np.sqrt(mean_squared_error(y_test, y_pred_test)):.4f}) print(fTest MAE: {mean_absolute_error(y_test, y_pred_test):.4f}) # 方向准确率 direction_acc np.mean((y_test 0) (y_pred_test 0)) print(fDirection Accuracy: {direction_acc:.4f}) # 残差自相关 from statsmodels.graphics.tsaplots import plot_acf plot_acf(residuals, lags20)如果方向准确率只有50%左右说明模型没有学到方向信息只是在“抄近道”。如果残差自相关图显示前几阶有显著自相关说明模型漏掉了短期依赖。7.4 结果解读与改进方向假设测试集RMSE0.03MAE0.02方向准确率52%。这个结果说明模型在幅度预测上还行但方向预测几乎随机。改进方向有以下几个第一加入更多特征。比如技术指标MACD、RSI、市场情绪指标、行业指数等。特征越丰富模型越有可能学到真正的规律。第二用分类模型代替回归模型。把预测问题转化为分类问题预测未来涨跌。分类模型会更关注方向而不是幅度。第三用集成模型。用多个不同架构的模型做Stacking比如LightGBMLSTMTransformer。集成能抵消单个模型的偏差。第四调整标签。不要用未来5日收益率用未来5日收益率的分位数。这样模型会更关注相对位置而不是绝对幅度。我试过用分类模型集成的方式方向准确率能提升到55%左右。虽然提升不大但在金融时序预测里55%的方向准确率已经能产生正收益了。8. 一些个人体会做时序预测这几年我最大的体会是模型不是越复杂越好数据理解和特征工程才是关键。很多项目失败不是因为模型不够强而是因为数据里的规律本身就不稳定或者模型学到的只是虚假相关。另一个体会是一定要做样本外测试而且只能做一次。我见过太多人反复用样本外数据调参最后模型在样本外表现很好一上真实业务就崩了。样本外数据是最后的照妖镜用一次就没了。最后分享一个小技巧画预测值vs真实值的散点图。这张图比任何指标都直观。如果散点集中在45度线附近说明模型预测准确。如果散点分布很散或者有明显的偏差说明模型有问题。我一般会在模型开发过程中反复画这张图直到散点分布满意为止。时序预测这条路不好走但走通了价值很大。希望这篇文章能帮你少踩几个坑早日做出真正“理解”数据的模型。
返回列表