4、平稳性与差分:ADF检验、KPSS检验、差分操作、白噪声检验
说到时序预测,有个坎儿你早晚得迈过去——平稳性。
我刚开始做时序项目时,上来就怼模型,结果预测值直接飞了。后来才发现,数据本身就不平稳。你想想看,一个上下乱窜的序列,模型怎么可能学得稳?
这一节,咱们就把平稳性这件事彻底聊透。包括怎么检验、怎么处理、以及处理完怎么确认。
4.1 什么是平稳性?
平稳性,说白了就是数据的统计性质不随时间变化。具体来说,均值、方差、自协方差都保持恒定。
我习惯把平稳序列想象成一个“老实人”——它虽然会波动,但始终围绕一个固定的均值来回晃,不会越跑越偏。
非平稳序列呢?就像喝醉了酒走路,方向飘忽不定,均值一直在变。这种数据直接建模,结果基本靠蒙。
平稳性的两种类型:
- 严平稳:所有统计性质都不随时间变化。现实中几乎不存在,了解一下就行。
- 弱平稳(宽平稳):均值恒定、方差恒定、自协方差只与时间间隔有关。我们平时说的平稳,指的就是这个。
4.2 怎么检验平稳性?
光靠肉眼看图不靠谱。我见过太多人看着图觉得“挺稳的”,结果一检验就翻车。咱们得用统计方法说话。
4.2.1 ADF检验(Augmented Dickey-Fuller Test)
ADF检验是最常用的单位根检验方法。它的原假设是:序列存在单位根,即非平稳。
如果p值小于0.05,就拒绝原假设,认为序列平稳。反之,p值大于0.05,说明序列非平稳。
from statsmodels.tsa.stattools import adfuller
# 假设 data 是你的时序数据
result = adfuller(data)
print(f'ADF统计量: {result[0]}')
print(f'p值: {result[1]}')
if result[1] < 0.05:
print('序列平稳')
else:
print('序列非平稳,需要差分')
我的经验:ADF检验对滞后阶数的选择比较敏感。我一般用AIC自动选择滞后阶数,结果更稳定。另外,如果数据有明显的趋势或季节性,记得加上'regression'参数,比如'ct'(含趋势和常数项)。
4.2.2 KPSS检验(Kwiatkowski-Phillips-Schmidt-Shin Test)
KPSS检验和ADF正好相反。它的原假设是:序列是平稳的。
如果p值小于0.05,拒绝原假设,认为序列非平稳。反之,p值大于0.05,认为序列平稳。
from statsmodels.tsa.stattools import kpss
result = kpss(data, regression='ct')
print(f'KPSS统计量: {result[0]}')
print(f'p值: {result[1]}')
if result[1] < 0.05:
print('序列非平稳')
else:
print('序列平稳')
注意:ADF和KPSS的结果有时会矛盾。比如ADF说平稳,KPSS说非平稳。这时候怎么办?
我个人习惯:两个都做。如果结果一致,直接判断。如果不一致,倾向于认为序列非平稳,先做差分再说。宁可多差分一次,也别漏掉。
4.3 差分操作
差分是处理非平稳序列最常用的方法。它的原理很简单:用当前值减去前一个值。
# 一阶差分
diff_1 = data.diff().dropna()
# 二阶差分(如果一阶后还不平稳)
diff_2 = data.diff().diff().dropna()
为什么差分能消除非平稳性?因为很多非平稳序列的本质是“随机游走”,差分后变成了白噪声或平稳序列。
我记得有个项目,数据有明显的线性趋势,一阶差分后直接变平稳了。但也有个坑——过度差分。差分次数太多,会丢失信息,甚至引入虚假的自相关。
差分次数的选择:
- 一般不超过2阶。超过2阶还不行,考虑其他方法(比如对数变换、季节差分)。
- 每次差分后都做ADF检验,直到p值小于0.05为止。
- 注意:差分后的序列长度会减少。一阶差分少1个点,二阶差分少2个点。
4.4 白噪声检验
差分完之后,别急着建模。先确认一下:差分后的序列是不是白噪声?
白噪声意味着序列中没有任何可用的信息了,全是随机波动。如果是白噪声,那建模就没意义了。
4.4.1 Ljung-Box检验
Ljung-Box检验用于判断序列是否存在自相关。原假设是:序列是白噪声。
如果p值大于0.05,接受原假设,认为序列是白噪声。反之,p值小于0.05,说明存在自相关,可以继续建模。
from statsmodels.stats.diagnostic import acorr_ljungbox
# 对差分后的序列做白噪声检验
result = acorr_ljungbox(diff_1, lags=[10, 20, 30], return_df=True)
print(result)
我的习惯:我会看多个滞后阶数的p值。如果所有阶数的p值都大于0.05,那基本可以断定是白噪声了。如果只有个别阶数显著,可能是偶然,我会再检查一下自相关图(ACF)。
4.5 知识体系图
下面这张图总结了平稳性检验与差分的完整流程,我画出来方便你对照着做。
4.6 避坑指南
最后,分享几个我踩过的坑:
- 不要只看一种检验:我曾经只做ADF,结果序列被判定为平稳,但建模效果很差。后来加上KPSS才发现问题。两个检验一起做,交叉验证更靠谱。
- 差分后别忘了检查白噪声:有个项目我差分到二阶才平稳,结果一检验,是白噪声。白忙活一场。所以差分后先做Ljung-Box,确认有信息再建模。
- 季节性数据要特殊处理:普通差分对季节性无效。如果数据有周期性,需要用季节差分(比如12阶差分)。这个后面会细讲。
- 差分次数不是越多越好:过度差分会破坏数据的内在结构。我一般控制在2阶以内,实在不行就考虑对数变换或Box-Cox变换。
一个小技巧:如果你不确定差分次数,可以画一下ACF图。如果ACF衰减很慢,说明需要差分。如果ACF在滞后1阶后迅速截尾,说明差分次数可能够了。
嗯,平稳性这部分就聊到这儿。记住一句话:先检验,再差分,后检验。这个流程走下来,你的数据基本就准备好了。