3、时间序列分解:趋势、季节性、残差分解(STL, X13-ARIMA)
时间序列分解,说白了就是把一个乱糟糟的序列拆成几块。
哪几块?趋势、季节性、还有残差。我刚开始做时序预测那会儿,拿到数据就直接上模型,结果效果惨不忍睹。后来才明白——你不把数据的“底裤”扒干净,模型根本不知道它在学什么。
3.1 为什么要做分解?
你想想看,一个时间序列里其实藏着三种信号:
- 趋势(Trend):长期向上还是向下?比如GDP逐年增长。
- 季节性(Seasonal):固定周期内的波动。比如电商销量每年双11冲高。
- 残差(Residual):剩下的随机噪声。说白了就是“解释不了的部分”。
我个人习惯,拿到任何时序数据,第一步就是做分解。为什么?因为很多模型(比如ARIMA、Prophet)对数据的平稳性有要求。你把趋势和季节性拆掉,剩下的残差如果还是乱七八糟,那说明数据本身就有问题。
核心观点: 分解不是预处理,而是理解数据的起点。
3.2 经典方法:STL 分解
STL(Seasonal-Trend decomposition using LOESS)是我最常用的方法。它用局部加权回归来拟合趋势和季节成分,非常灵活。
STL 的核心参数
| 参数 | 含义 | 我的建议 |
|---|---|---|
| period | 季节周期长度 | 比如日数据周期=7,月数据周期=12 |
| seasonal | 季节成分的平滑度 | 越大越平滑,我一般设7-15 |
| trend | 趋势成分的平滑度 | 经验值:seasonal的1.5倍左右 |
| robust | 是否抗异常值 | 数据有毛刺时一定要开 |
代码实现其实很简单,statsmodels 里直接调:
import statsmodels.api as sm
# 假设 data 是 pandas Series,索引为日期
stl = sm.tsa.STL(data, period=7, seasonal=13, robust=True)
result = stl.fit()
trend = result.trend
seasonal = result.seasonal
residual = result.resid
嗯,这里要注意:STL 对缺失值很敏感。我在项目中遇到过,数据里有两个空值,结果分解出来的残差直接炸了。所以记得先做插值。
3.3 进阶方法:X13-ARIMA
X13-ARIMA 是美国人口普查局开发的,比 STL 更“工业化”。它不光做分解,还能自动检测异常值、交易日效应、移动假日影响。
说白了,STL 是“手工活”,X13 是“流水线”。
什么时候用 X13?
- 数据有明确的日历效应(比如春节、黑五)
- 需要官方统计级别的分解结果
- 数据量较大,需要自动化处理
不过 X13 的安装有点麻烦,需要装 Java 环境。我建议直接用 statsmodels 的包装接口:
from statsmodels.tsa.x13 import x13_arima_analysis
# 需要先安装 x13as 二进制文件
results = x13_arima_analysis(data, log=True, outlier=True)
print(results.seasadj) # 季节调整后的序列
避坑指南: 我曾经在 Windows 上折腾 X13 装了一天。如果你只是做快速分析,STL 完全够用。X13 更适合生产环境或学术论文。
3.4 分解后的应用:到底怎么用?
分解不是终点,而是起点。我个人习惯把分解结果用在三个地方:
- 特征工程:把趋势、季节性作为额外特征喂给模型。比如 LSTM 里同时输入原始值和季节成分。
- 异常检测:残差如果突然变大,说明有异常事件。我在金融风控项目里就用这个逻辑抓过数据造假。
- 模型选择:如果残差是白噪声,说明分解很干净,直接用季节ARIMA就行。如果残差还有结构,那得换更复杂的模型。
小技巧: 分解后记得画图看看。趋势线如果太“抖”,说明参数设小了。季节成分如果每年形状不一样,说明数据有“季节漂移”,这时候可以考虑用 Prophet。
3.5 知识体系图:分解的核心逻辑
下面这张图是我自己总结的,帮你理清思路:
3.6 实战建议:选哪个?
最后给个总结,帮你快速决策:
- 快速探索数据 → 用 STL,一行代码搞定
- 生产环境、需要稳健性 → 用 X13-ARIMA,但要做好环境配置
- 数据有复杂日历效应 → 优先 X13,或者考虑 Prophet
- 只是想做个基线模型 → 直接用移动平均分解,简单粗暴
我记得有一次,一个电商客户的数据里,季节性周期不是7天而是10天(因为他们的促销节奏是10天一轮)。STL 默认周期设成7,结果分解出来的残差里全是结构。后来我改成10,一切就正常了。所以啊,理解业务比理解算法更重要。
公众号:蓝海资料掘金营,微信deep3321