时间序列预测这事,做久了都会遇到同一个坎:单模型打不过复杂序列。真实业务里的数据,往往既带着长期趋势,又有周期波动,还叠着噪声和突发扰动,指望一个模型通吃,基本不现实。我去年做一个设备运行指标预测项目时,试过直接用XGBoost、随机森林、甚至LSTM硬怼原始序列,效果都差强人意,预测曲线老是滞后一拍,高峰和低谷的拟合也都很勉强。后来换成“非线性二次分解 + 多模型融合”这套思路,把序列先拆干净,再让每个模型负责自己最擅长的分量,效果提升非常明显。
这篇文章就把这套“基于非线性二次分解的Ridge-RF-XGBoost时间序列预测”完整拆开讲,包括为什么分解能提升预测、二次分解比一次分解强在哪、三个模型各自的定位和融合方式,以及全流程Python代码怎么落地。无论你是做量化、做工业指标预测,还是研究负荷预测,这套框架的思路和代码都可以直接拿来改。
1. 为什么时间序列预测需要“分解+多模型组合”
1.1 时间序列预测的核心痛点
时间序列预测的本质,是从历史数据里找到规律,然后外推未来。但真实世界的序列往往由多个不同频率、不同复杂度的成分叠加而成:长期趋势、周期性波动、季节性变化、节假日效应、随机噪声,甚至偶发的异常脉冲。这些成分混在一起,会互相干扰模型的判断。
举个例子,一条包含上升趋势和剧烈短期波动的序列,如果直接扔给XGBoost,模型会把趋势和波动一起学,结果就是趋势没学准,波动也没抓住。树的切分点在拟合高频噪声,而趋势信息被稀释。我在实际项目中试过直接对原始序列建模,R²能到0.8,但看残差图能明显发现,某些区段的残差有强烈的自相关性,这说明模型遗漏了本该捕捉的结构化信息。
这其实是时间序列预测和普通回归问题最大的区别:普通回归假设样本独立,而时间序列的样本之间存在强依赖,且这种依赖往往是多种时间尺度叠加的。单一模型面对这种混合信号,很难在“拟合趋势”和“捕捉波动”之间自动平衡。
1.2 分解为何有效:从“混合信号”到“单分量信号”
分解方法的逻辑很朴素,先把混合序列拆成若干个相对“纯净”的分量,再分别建模预测,最后把预测结果加起来。这样做的好处是,每个子序列的复杂度大幅降低,模型只需要学一种模式,拟合难度自然下降。
做一个类比,混合序列像是混音后的音乐文件,里面有低音鼓、人声、吉他、高音镲。直接用播放器去“预测”下一段旋律,难度很大;但如果先做分轨,把低音(低频趋势)、人声(中频周期)、镲声(高频波动)分别提取出来,再对每一轨单独预测,最后混音,成功的概率就要高得多。
分解方法有很多种,经典的有STL(季节趋势分解)、小波变换、EMD(经验模态分解),以及EMD的后继变体EEMD、CEEMDAN,还有VMD(变分模态分解)。它们的核心区别在于:
- STL:适合规律性强、季节周期明确的序列,但只能拆出趋势+季节+残差三部分,过于粗糙。
- EMD:数据自适应分解,不需要先验设定基函数,能把序列拆成多个IMF(本征模态函数),但存在模态混叠问题,相近频率的成分可能被分到不同IMF里。
- EEMD/CEEMDAN:在EMD基础上引入噪声辅助,缓解模态混叠。CEEMDAN(完全自适应噪声集合经验模态分解)进一步改进了EEMD分解不彻底、噪声残留的问题,分解结果具有完备性,重构误差极小。
- VMD:非递归分解算法,把信号分解转化为变分优化问题,能精确控制每个模态的中心频率和带宽,不会出现EMD的端点效应累积问题,但需要预设模态数K,且对惩罚因子α敏感。
我推荐的基础框架是CEEMDAN,它的自适应性最强,适合处理各种形态的复杂序列,这也是下面二次分解方案的第一层分解选择。
1.3 为什么我要做“二次”分解而不只是一次
一次分解能够提取主要成分,但问题在于,分解后的某些分量仍然可能很“脏”。尤其是一次分解得到的第一个IMF,往往包含最高频、最复杂的成分,噪声和短周期波动混合在一起;而最后一个残余分量(趋势项)通常已经很干净,不需要再拆。
所以二次分解的思路很直接:对一次分解后复杂度仍然较高的分量再做一次分解,把隐藏的结构进一步挖出来。我常用的策略是,先对原始序列做CEEMDAN分解,得到若干IMF和一个残余项;然后计算每个IMF的样本熵或方差贡献率,将复杂度最高的那个IMF(通常是IMF1)单独拎出来,再做一次VMD分解,把高频成分再拆成更细腻的子模态。
为什么不直接一次分解到底?因为EMD类方法对极值点分布敏感,一次分解的模态数有限,继续递归调用CEEMDAN容易把噪声也当作信号来拟合,反而引入过拟合。而用VMD做第二层则是另一种思路——VMD的频带划分更精确,能以一种受控的方式把高频成分按频带切分,和CEEMDAN形成互补。
“非线性”这三个字,在这里的含义是:分解算法本身是非线性的、数据自适应的,区别于傅里叶变换这种把序列硬拆成正弦波组合的线性方法。真实业务数据往往是非平稳、非线性的,传统线性分解无法准确分离成分,而非线性分解方法恰恰为此设计。
需要模型API调用? 免费领10W Token,多模型网关一键接入 Claude、DeepSeek 等主流模型。
2. Ridge-RF-XGBoost三模型组合的思路拆解
2.1 三个模型各自擅长什么
分解只是第一步,核心是预测。我之所以把Ridge、RF和XGBoost组合起来,是因为这三个模型特性互补,覆盖了从线性到非线性、从低方差到低偏差的完整谱系。
Ridge(岭回归)是线性模型L2正则化版本,它在普通线性回归基础上加了L2惩罚项,专门用来处理特征之间存在高度相关性的情况。分解后的子序列往往和滞后特征之间有较强的线性相关性,Ridge在这类场景下能给出稳定且可解释的预测结果,而且不容易过拟合。
Random Forest(随机森林)是Bagging思想的代表,它并行训练多棵决策树,每棵树在随机抽样的样本和随机选取的特征子集上训练,最后取平均。随机森林的优点是对非线性的拟合能力强、对异常值鲁棒、几乎不需要太多特征工程。在子序列预测中,RF很适合捕捉那些有非线性交互关系的特征组合。
XGBoost(极致梯度提升)是Boosting思想的代表,串行训练多棵决策树,一棵树拟合上一棵树的残差,通过不断减少残差来逼近真实值。XGBoost对非线性关系的拟合能力比RF更强,而且自带正则化、列抽样、学习率衰减等机制,配合调参往往能达到很高的精度。
2.2 为什么是“Ridge+RF+XGBoost”而不是其他组合
这个组合并不是随意的拼凑,而是刻意进行互补搭配。
Ridge负责的是序列中的线性趋势部分。CEEMDAN分解出的残余趋势项,通常是一条相对平滑的曲线,用Ridge拟合滞后特征和趋势的变化,简单高效,残差小,而且不会像树模型那样在平滑曲线上产生不必要的阶跃。
RF负责的是中低频的周期分量,这些分量有一定非线性,但相对稳定。RF对噪声不敏感,不容易出现过拟合,适合作为中庸而稳健的预测器。
XGBoost负责的是最高频、最复杂的成分。这些成分非线性强、特征交互多,需要XGBoost强大的拟合能力。虽然高频分量预测难度最大,但XGBoost能挖掘特征间复杂的交互关系,获得相对最好的结果。
三者的定位可以总结为:Ridge兜底线性趋势,RF稳住非线性周期,XGBoost攻坚高频复杂分量。这样的分工让每个模型都只处理自己最擅长的信号类型,而不是像单一模型那样逼着它学会所有模式。
2.3 融合策略与权重设计
模型融合有两条路线:一条是Stacking,用另一个模型学习各模型预测结果的最优组合;另一条是加权平均,直接对三个模型的预测值做线性组合。我在实践中更推荐后者,原因很简单:Stacking需要额外预留一折数据来训练元模型,容易造成信息泄露,而且元模型的解释性更差。
加权平均的权重设计也有讲究。简单等权平均是个保底方案,实测效果通常已经不错,但不是最优的。我常用的改进方式是误差倒数加权:
w_i = (1 / RMSE_i) / (1 / RMSE_1 + 1 / RMSE_2 + 1 / RMSE_3)
这个公式的逻辑很直观:哪个模型在验证集上的误差小,就给它更大的权重。由于高频分量预测难度大,XGBoost的权重往往最高,但也不是绝对,要根据数据实际分布来判断。
另外一个细节是:不同子序列的预测结果要相加回原始尺度,相加的次序无所谓,但要确保每个子序列都用对应的模型预测,并做反归一化后再相加。如果用标准化后的数据进行预测并直接相加,最后的结果需要整体反归一化,这一步千万不能搞错,否则预测值会整体偏移。
3. 非线性二次分解的Python实现
3.1 工具库选型与安装
实现这套流程,主要依赖以下几个Python库:
PyEMD:提供EMD、EEMD、CEEMDAN的实现vmdpy:VMD算法的Python实现numpy、pandas:数据处理scikit-learn:提供Ridge、RandomForestRegressor以及评估指标xgboost:XGBoost回归模型matplotlib:结果可视化
安装命令:
bash复制pip install PyEMD vmdpy xgboost scikit-learn pandas matplotlib
需要注意,PyEMD库的CEEMDAN接口在某些版本中有变更,建议确认安装的是最新版本。如果遇到“No module named PyEMD”报错,大概率是包名写错,正确导入方式是from PyEMD import CEEMDAN。
3.2 第一层分解:CEEMDAN分解
CEEMDAN的核心思想是在EMD的迭代过程中多次加入正负成对的白噪声,并对每次分解得到的IMF取平均,从而消除噪声对分解结果的影响,同时保证分解的完备性。
具体实现代码如下:
python复制import numpy as np
import pandas as pd
from PyEMD import CEEMDAN
# 假设 data 是一维 numpy 数组,长度 N
ceemdan = CEEMDAN(trials=50, parallel=False)
imfs = ceemdan(data) # 返回 shape = (n_imfs, N) 的数组
# 最后一个通常是残余趋势项
trend = imfs[-1]
n_imfs = imfs.shape[0]
这里有一个实际经验:trials参数控制加入白噪声的次数,默认几百次会导致运行速度很慢。我在工程里通常设为50,分解稳定性和运行时间能取得平衡。如果序列很长(超过几千个点),还可以考虑先用滑动窗口截断或用抽样压缩,避免CEEMDAN计算耗时过长。
分解完成后,把各IMF画出来看一遍非常有必要。正常情况应该是:IMF1最高频,频率逐渐降低,最后一个IMF是平滑的趋势线。如果发现某个IMF出现了明显的频率混叠(同一IMF里既有高频率又有低频率片段),说明分解效果不理想,可以调整CEEMDAN的噪声强度。
3.3 第二层分解:对高频分量做VMD再分解
第一层分解后,复杂度最高的IMF通常是IMF1。判断哪个IMF需要二次分解,我用的是样本熵(Sample Entropy),样本熵越高,说明序列的自相似性越低、复杂度越高。
VMD需要预设两个关键参数:模态数K和惩罚因子α。模态数K不容易一次设准,我的经验是用中心频率判据:先尝试K从2到6各跑一遍,观察各模态的中心频率是否分离。如果两个模态的中心频率非常接近,说明K设大了;如果某个模态的中心频率异常高或异常低,说明K可能小了。
python复制from vmdpy import VMD
# 对 high_freq_imf 做 VMD 分解
K = 3
alpha = 2000
tau = 0.0
DC = 0
init = 1
tol = 1e-7
u, u_hat, omega = VMD(high_freq_imf, alpha, tau, K, DC, init, tol)
# u 的 shape = (K, N)
tau设为0是标准模式,DC为0表示第一个分量不强制指定为直流分量。分解出的K个子模态,加上原序列CCEMDAN分解出的其他IMF,一起构成最终的预测输入集合。
有人会问,为什么第二层不继续用CEEMDAN?因为CEEMDAN对已经分解过一次的高频信号,容易把噪声放大成新模态,而VMD通过带限约束,能更精确地按频带切分信号,不会出现过度分解的问题。两层分解用不同算法,互补效果更佳。
3.4 重构与数据准备
二次分解后,我们得到了一组子序列。每个子序列都可以看作是原始序列的一个相对独立的成分,接下来需要分别对它们做预测。这里有个细节:我们不直接预测子序列本身,而是为每个子序列构造监督学习所需的特征矩阵——用前几个时刻的值预测下一个时刻的值。
我在项目中通常用24步滞后窗口(即用t-1到t-24时刻的值预测t时刻的值)。窗口大小可以根据数据频率调整:如果是日粒度数据,7或30比较合理;如果是小时粒度数据,24或168更合适。
每个子序列都需要做归一化,我推荐使用MinMaxScaler,将数据缩放到0到1之间。树模型(RF、XGBoost)对尺度不敏感,但Ridge是线性模型,对特征尺度非常敏感,不归一化会导致Ridge的正则化惩罚对不同特征权重不一致。
有一个容易踩的坑:所有子序列要分别用各自的scaler归一化,不能共用原始序列的scaler。因为各子序列的数值范围差异可能很大,如果共用scaler,低频分量的微小变化在归一化后可能被压缩到无法区分。
4. Ridge-RF-XGBoost模型的训练与预测实现
4.1 滑动窗口特征构建
把每个子序列变成监督学习格式,需要构造特征矩阵。下面这个函数是通用的滑动窗口构造器:
python复制def create_dataset(data, lookback=24):
X, y = [], []
for i in range(lookback, len(data)):
X.append(data[i - lookback:i])
y.append(data[i])
return np.array(X), np.array(y)
数据集划分要注意不能用随机划分,时间序列必须按时间顺序切分。实践中我通常按8:1:1划分训练、验证、测试集,且三个集合在时间上必须连续。如果用随机交叉验证,会产生严重的数据泄露,预测效果虚高,放到线上就翻车。
4.2 模型训练与超参数要点
三个模型的训练逻辑并不复杂,关键是超参数的设定。
Ridge模型:
python复制from sklearn.linear_model import Ridge
ridge = Ridge(alpha=1.0)
ridge.fit(X_train, y_train)
alpha需要调,我常用交叉验证或验证集上的表现来选值。数据经过归一化后,alpha通常取0.1到10之间。如果预测曲线抖动剧烈,可以适当增大alpha。
RF模型:
python复制from sklearn.ensemble import RandomForestRegressor
rf = RandomForestRegressor(
n_estimators=300,
max_depth=10,
min_samples_leaf=3,
random_state=42
)
rf.fit(X_train, y_train)
随机森林的核心参数是n_estimators、max_depth和min_samples_leaf。max_depth限制树深能有效防止过拟合,特别是对高频分量来说,树太深会把噪声也学进去。我的经验是max_depth在5到15之间、min_samples_leaf在3到5之间会比较稳健。
XGBoost模型:
python复制import xgboost as xgb
xgb_model = xgb.XGBRegressor(
n_estimators=300,
learning_rate=0.05,
max_depth=5,
subsample=0.8,
colsample_bytree=0.8,
reg_lambda=1.0,
random_state=42
)
xgb_model.fit(X_train, y_train)
XGBoost的调参空间很大,但核心就几项:learning_rate设小一点(0.01~0.1),n_estimators相应增多;max_depth控制在4到8之间,太深容易过拟合;subsample和colsample_bytree设为0.7到0.9,既能增强鲁棒性,又能减少过拟合。
这里需要特别强调:分解后的每个子序列是单独建模的,所以三个模型的组合不是只有一个模型实例,而是每个子序列都会对应一组模型。也就是说,如果有8个子序列,那么实际训练了8组模型,每组里各有一个Ridge、一个RF、一个XGBoost。模型数量会比较多,但每个子序列的训练数据量是相同的,训练时间总体可控。
4.3 预测叠加与结果重构
预测阶段,把每个子序列未来时刻的预测值计算出来后,要按照分解的逆过程叠加起来。如果第二层VMD把IMF1拆成了K个子模态,那么IMF1的最终预测值就是这K个子模态预测值之和;再把IMF1预测值和其余IMF预测值及趋势项预测值相加,得到最终预测结果。
代码如下:
python复制forecast = np.zeros(n_forecast)
for sub in all_sub_series:
pred = model_weights_average(sub_model_preds)
forecast += pred
# 反归一化到原始尺度
forecast = scaler_global.inverse_transform(forecast.reshape(-1, 1)).flatten()
权重融合部分,我用的是误差倒数加权。具体做法是:在验证集上分别计算三个模型预测值的RMSE,然后计算权重并应用到测试集预测结果上。注意权重是基于验证集算出来的,不能用测试集去算权重,否则就是信息泄露。
融合函数示例:
python复制def weighted_average(preds_dict, rmse_dict):
weights = {}
inv_total = 0
for name, rmse in rmse_dict.items():
inv = 1.0 / max(rmse, 1e-10)
inv_total += inv
weights[name] = inv
for name in weights:
weights[name] /= inv_total
return sum(preds_dict[name] * weights[name] for name in preds_dict)
5. 实验评估与问题排查实录
5.1 评估指标与可视化对比
预测结果好不好,不能只看拟合曲线,要用量化指标评价。我常用的指标有四个:
- RMSE(均方根误差):对大误差敏感,适合衡量整体预测偏差
- MAE(平均绝对误差):更直观,能反映平均偏差
- MAPE(平均绝对百分比误差):相对误差,便于跨数据比较
- R²(决定系数):模型解释数据变异的能力,越接近1越好
以我最近一次用电负荷预测实验为例,原始序列直接套XGBoost的RMSE是2.34,而使用非线性二次分解+Ridge-RF-XGBoost融合后,RMSE降到了1.32,提升幅度约43.6%。MAPE也从原来的5.8%降到了3.2%。这个提升主要来源于分解之后,低频趋势分量被Ridge拟合得极准,高频分量被XGBoost单独学习后不再受其他成分干扰。
可视化时,光画出预测值和真实值不够,还要画误差区间和残差序列。如果残差仍存在明显周期性,说明分解或建模还不到位。比如我遇到过残差在每7天出现一个低谷的情况,说明数据有周周期性没有被充分分解出来,后来在特征中额外加入了“星期几”这个特征,才算解决了问题。
5.2 我踩过的坑
这套方法看似简单,实际操作中坑不少,我把最常见的几个列出来。
第一个坑是CEEMDAN分解的边界效应。由于首尾处极值点不完整,分解结果在两端会有较大的摆动。如果直接拿最后一段数据做预测,这个边界摆动会毁掉预测结果。我常用的处理方式是:在分解前在序列两端各扩展一段数据(比如用镜像延拓,或者直接用最后一小段数据重复拼接),分解后丢弃扩展部分,只保留原始范围内的分解结果。虽然会增加一点点计算量,但能显著提升预测起始段的稳定性。
第二个坑是VMD的模态数K取值。K设小了,高频成分没有完全分离,单子模态里仍混着多频率成分;K设大了,会出现虚假模态,导致模型过度拟合噪声。我在实践中的经验是:结合中心频率判断。K在2~5之间,观察VMD得到的模态中心频率是否依次递增且间距合理。如果某两个相邻模态的中心频率差值小于10%,说明K取值过大,需要调低。
第三个坑是模型融合权重的不稳定性。误差倒数权重虽然简单有效,但如果验证集本身噪声较大,算出来的RMSE不一定代表真实泛化误差,权重会失真。解决方案是采用滚动验证法:在验证集上用滑动的多个时间窗口分别计算RMSE再取均值,这样权重更稳健。
第四个坑是数据泄漏。一个常见错误是在整体数据上做归一化,再切分训练测试集,导致测试集的信息混入了训练阶段。正确做法是:先在训练集上fit scaler,再transform训练集、验证集和测试集。同样,分解算法如果是在全序列上一次性做分解,那测试段的信息也会污染分解结果。严格的做法是只在训练段内做分解,但如果序列过长且分解算法需要全局信息,至少要用滚动分解的方式,保证预测时只用到了预测点之前的数据。
5.3 常见问题速查表
我把高频问题整理成一张表,方便你对照排查。
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| CEEMDAN运行太慢 | trial次数过多、序列过长 | 降低trial次数到30~50,或先降采样 |
| 分解结果首尾剧烈波动 | 边界效应 | 添加镜像延拓,分解后去除扩展区域 |
| VMD模态中心频率过近 | K值偏大 | 减少K,重新运行直到频率合理分布 |
| Ridge预测结果是一条直线 | 特征丢失或alpha过大 | 检查是否用了归一化,调低alpha或增加滞后特征数 |
| XGBoost过拟合严重 | max_depth过深、学习率太高 | 调低max_depth到4~6,降低learning_rate |
| 融合后效果反而不如单模型 | 权重计算使用了测试集 | 权重必须在验证集上计算,滚动验证更合理 |
| 预测序列出现整体偏移 | 反归一化时用了错误的scaler | 依次检查各子序列的scaler是否匹配,是否最后整体反归一化 |
另外有一个方法论层面的建议:这套“分解+多模型融合”的方法,并不是所有数据都适用。如果序列本身很简单,比如纯线性趋势加微弱噪声,直接上Ridge就够了,分解和多模型只会增加复杂度且无实质提升。我的判断标准是:先对序列做一次平稳性检验和复杂度分析,如果序列的样本熵较高、非平稳性强,才有必要动用这套组合方案。
6. 工具选型解析:为什么用CEEMDAN+VMD而不是其他组合
6.1 CEEMDAN与EEMD、EMD的对比
EMD是最早的经验模态分解算法,但它有一个明显短板:模态混叠。当一个IMF中同时包含多个频率成分时,后续建模的准确性会受到很大影响,因为模型无法区分这是同一模式还是不同模式。EEMD通过加入白噪声来解决这个问题,但代价是分解结果会残留白噪声影响,重构信号与原始信号不完全相等。CEEMDAN则在此基础上改进了噪声添加方式——每次分解都用上一次的残差来指导下一步的噪声添加,让分解过程更稳健,并且最终重构误差接近零。
如果数据本身信噪比较低,我强烈建议直接用CEEMDAN而不是EMD。从实测效果看,CEEMDAN分解出的IMF序列更平稳、更“干净”,后续预测的误差也更小。
6.2 VMD参数敏感性分析
VMD相比EMD系列,最大的优势是可以显式控制频带数量,但代价是参数敏感。除了K之外,惩罚因子α非常关键:α越大,各模态的带宽越小,分出来的子序列越窄频,但也越容易把原信号中的有效成分滤掉;α越小,带宽越宽,各模态越容易混叠。对于金融时间序列或设备振动信号,α在1000~3000之间通常表现良好;对于数据特征不明确的场景,建议用网格搜索。
python复制best_alpha = 2000
for alpha in [500, 1000, 2000, 3000, 5000]:
u, _, omega = VMD(high_freq_imf, alpha, tau, K, DC, init, tol)
# 计算各模态与原始分量的相关性,选择综合效果最好的 alpha
选择依据是:子模态与原始高频分量的相关系数要高,同时各子模态之间的相关系数要尽量低,这样既保证分解保留了原始信息,又确保模态之间互相独立。
6.3 有没有必要引入深度学习方法?
经常有人问我:既然都做到二次分解了,为什么不直接上LSTM或者Transformer?
我的观点是:看数据量。深度学习模型需要大量数据来学习复杂模式,如果只有几千个点的时间序列,LSTM反而容易过拟合,效果不如树模型。而且深度学习模型的可解释性弱,超参数调优成本高,在工业应用中调试周期太长。
当然,如果你有几十万以上的数据点,并且硬件资源充足,可以在分解后用LSTM替代Ridge-RF-XGBoost组合来预测各子序列。我做过一组对比实验:在10万级数据量下,LSTM预测高频分量时确实略优于XGBoost,但在低频分量上两者差距不大,而且LSTM训练时间长了数倍。所以我的结论是:中小规模数据用Ridge-RF-XGBoost融合已经足够,大数据量再考虑深度学习。
7. 实操总结与个人经验
最后说点个人体会。这套“非线性二次分解+Ridge-RF-XGBoost”方案,我从最初构思到现在跑过十几组不同的数据,有工业传感器数据、电力负荷数据、交通流量数据,整体感受是:分解带来的收益往往比换更花哨的模型大得多。很多时候我们觉得数据太难预测,其实不是模型不够强,而是信号太混浊。把混浊的信号拆干净,基础模型已经能做得不错。
有一个实用的技巧分享给正在调这套方法的你:预测完以后,务必对预测残差再做一次CEEMDAN分解,看残差里是否还有明显的低频成分。如果残差的趋势项不是平稳线,说明你前期的分解还不够充分,需要调整第一层或第二层的参数。我经常在这一步发现,某些看似已经成功的预测案例,其实残差里还藏着周期性信号,把这一步处理好,预测精度还能再上一个台阶。
另外,这套方法虽然复杂,但每一步都有独立的价值,建议不要贸然删减。如果时间紧张,可以减少分解层数或模型数量,但至少保留“一次分解+单模型”的底线,否则就失去了这套框架最核心的意义。代码的整体流程不算长,但每一步调试和检验都值得投入时间,毕竟时间序列预测这种问题,细节决定成败。
