4、平稳性检验:什么是平稳性?ADF检验、KPSS检验,以及差分操作

各位同学,咱们今天聊一个时间序列分析里绕不开的话题——平稳性

说实话,我刚开始接触时间序列那会儿,觉得平稳性就是个理论概念,离实战很远。直到有一次,我用非平稳数据直接建模,结果预测出来的曲线跟实际走势完全反着走……嗯,那场面挺尴尬的。从那以后,我再也不敢小看平稳性检验了。

4.1 什么是平稳性?

平稳性,说白了就是:时间序列的统计性质不随时间变化

具体来说,一个平稳序列应该满足三个条件:

  • 均值恒定:序列的均值不随时间变化,始终围绕一个固定值波动
  • 方差恒定:序列的波动幅度不随时间变化,不会出现“前面很平稳、后面剧烈震荡”的情况
  • 协方差只与时间间隔有关:两个时间点的相关性只取决于它们相隔多远,而不取决于具体在哪个时间点

我习惯把平稳序列想象成一个“安分守己”的人——情绪稳定,行为规律,不会突然暴走也不会突然躺平。而非平稳序列呢?就像个情绪过山车,你永远猜不到它下一秒要干嘛。

重要提醒:大多数时间序列模型(比如ARIMA)都要求数据是平稳的。如果你拿非平稳数据直接建模,结果基本就是“垃圾进,垃圾出”。

举个例子:

  • 平稳序列:白噪声、某台机器的稳定振动信号
  • 非平稳序列:股票价格(有趋势)、季节性气温数据(有周期)、GDP增长(有趋势+周期)

4.2 为什么要检验平稳性?

你可能会问:我直接建模不行吗?为什么要多此一举?

原因很简单:非平稳数据会导致“伪回归”问题

我在项目中遇到过这样一个案例:分析某电商平台的日销售额和广告投放量,发现两者相关系数高达0.9。乍一看,广告效果很好对吧?但仔细一查,两个序列都有明显的上升趋势——销售额在涨,广告费也在涨,它们只是“碰巧”都在涨,实际上并没有因果关系。这就是典型的伪回归。

所以,平稳性检验不是学术上的花架子,而是实战中的“避坑指南”。

4.3 ADF检验(单位根检验)

ADF检验,全称是Augmented Dickey-Fuller检验。它是目前最常用的平稳性检验方法之一。

它的核心思想是:检验序列是否存在单位根

什么叫单位根?简单理解:如果序列存在单位根,说明它是一个随机游走过程,也就是非平稳的。如果不存在单位根,说明序列是平稳的。

ADF检验的假设是这样的:

  • 原假设H₀:序列存在单位根(非平稳)
  • 备择假设H₁:序列不存在单位根(平稳)

判断标准:如果p值小于显著性水平(通常取0.05),就拒绝原假设,认为序列是平稳的。

我的经验:ADF检验对趋势性数据比较敏感,但对季节性数据不太敏感。如果你怀疑数据有季节性,建议配合其他方法一起使用。

来看代码实现:

from statsmodels.tsa.stattools import adfuller
import pandas as pd

# 假设data是一个时间序列
result = adfuller(data)

print(f'ADF统计量: {result[0]}')
print(f'p值: {result[1]}')
print(f'临界值: {result[4]}')

# 判断是否平稳
if result[1] < 0.05:
    print('拒绝原假设,序列是平稳的')
else:
    print('无法拒绝原假设,序列是非平稳的')

输出结果解读:

  • ADF统计量:越小越好,越负越好
  • p值:小于0.05说明平稳
  • 临界值:1%、5%、10%三个水平,ADF统计量小于临界值则拒绝原假设

4.4 KPSS检验

KPSS检验是ADF检验的“互补兄弟”。它的假设正好反过来:

  • 原假设H₀:序列是平稳的
  • 备择假设H₁:序列存在单位根(非平稳)

你想想看,为什么需要两个检验?

因为ADF检验的“功效”不是100%的。有时候数据明明是非平稳的,ADF检验却告诉你它是平稳的(这叫“第二类错误”)。反过来,KPSS检验也可能犯错。

所以我个人的习惯是:两个检验一起做,交叉验证

我曾经踩过的坑:只用了ADF检验,结果p值刚好在0.05附近,我判断为平稳。后来用KPSS一测,发现其实是非平稳的。两个检验结果不一致时,要小心!

代码实现:

from statsmodels.tsa.stattools import kpss

result_kpss = kpss(data)

print(f'KPSS统计量: {result_kpss[0]}')
print(f'p值: {result_kpss[1]}')

if result_kpss[1] < 0.05:
    print('拒绝原假设,序列是非平稳的')
else:
    print('无法拒绝原假设,序列是平稳的')

4.5 两种检验的对比

对比项 ADF检验 KPSS检验
原假设 非平稳(有单位根) 平稳
备择假设 平稳 非平稳
适用场景 检测趋势性非平稳 检测趋势平稳或差分平稳
常见问题 可能漏检某些非平稳 可能误判趋势为平稳
我的建议 作为主要检验 作为辅助验证

4.6 差分操作

如果数据不平稳怎么办?别急,我们有“差分”这个神器。

差分,说白了就是:用当前值减去前一个值

一阶差分的公式很简单:

diff_t = x_t - x_{t-1}

为什么差分能消除非平稳性?

因为很多非平稳序列的“不平稳”来自于趋势。差分之后,我们关注的是“变化量”而不是“绝对值”,趋势就被消除了。

代码实现:

# 一阶差分
diff_1 = data.diff().dropna()

# 二阶差分(如果一阶还不够平稳)
diff_2 = data.diff().diff().dropna()

# 检查差分后的平稳性
result_diff = adfuller(diff_1)
print(f'差分后p值: {result_diff[1]}')

我的经验:大多数金融时间序列,一阶差分就够了。如果一阶差分后还不平稳,二阶差分基本能搞定。但别超过二阶,否则会丢失太多信息。

4.7 知识体系总览

下面我用一张图来总结本章的核心逻辑:

平稳性检验知识体系 原始时间序列 是否平稳? 直接建模 差分操作(一阶/二阶) ADF检验 KPSS检验 交叉验证

4.8 实战建议

最后,我给大家总结几条实战中的“黄金法则”:

  1. 先画图,再检验:别一上来就跑代码。先画出时序图,肉眼观察有没有趋势、季节性、突变点。很多时候,看图就能判断个七七八八。
  2. ADF+KPSS双保险:两个检验结果一致,基本可以放心。如果不一致,以ADF为主,但要对结果保持警惕。
  3. 差分不是万能的:差分能消除趋势,但消除不了季节性。如果数据有季节性,需要做季节性差分或使用SARIMA模型。
  4. 别过度差分:差分次数越多,丢失的信息越多。一阶不行就二阶,二阶还不行,考虑其他方法(比如对数变换、Box-Cox变换)。
  5. 差分后记得检查:做完差分,一定要重新做平稳性检验,确认数据真的平稳了再建模。

一句话总结:平稳性检验是时间序列建模的“体检”,ADF和KPSS是体检报告,差分是治疗方案。体检不过关,别急着上手术台。


公众号:蓝海资料掘金营,微信deep3321