4、平稳性检验(ADF):ADF检验原理、Python实现、p-value解读、常见陷阱
平稳性检验,说白了就是判断一个时间序列有没有“根”。
我刚开始做协整配对时,觉得这步就是个形式。后来踩了坑才发现——ADF检验没过,后面所有分析都是白搭。你想想看,两个非平稳序列直接做回归,大概率是伪回归,看着相关系数挺高,其实啥关系没有。
4.1 ADF检验原理
ADF全称是Augmented Dickey-Fuller test。它的核心思想很简单:检验序列是否存在单位根。
什么是单位根?我习惯这么理解:
- 平稳序列:冲击是暂时的,过段时间会回到均值
- 单位根序列:冲击是永久的,回不去了
ADF检验的回归方程长这样:
Δy_t = α + βt + γy_{t-1} + δ₁Δy_{t-1} + ... + δₚΔy_{t-p} + ε_t
关键看γ这个系数。如果γ=0,说明存在单位根,序列非平稳。如果γ<0,说明序列平稳。
原假设H₀:γ=0(存在单位根,非平稳)
备择假设H₁:γ<0(不存在单位根,平稳)
嗯,这里要注意:ADF检验是单侧检验。只看左边。
4.2 Python实现
Python里实现ADF检验,我一般用statsmodels库。代码非常简洁:
import numpy as np
import pandas as pd
from statsmodels.tsa.stattools import adfuller
# 模拟一个随机游走(非平稳)
np.random.seed(42)
n = 200
random_walk = np.cumsum(np.random.randn(n))
# ADF检验
result = adfuller(random_walk, autolag='AIC')
print(f'ADF统计量: {result[0]:.4f}')
print(f'p-value: {result[1]:.4f}')
print(f'临界值:')
for key, value in result[4].items():
print(f' {key}: {value:.4f}')
print(f'是否平稳: {"是" if result[1] < 0.05 else "否"}')
输出结果:
ADF统计量: -0.8921
p-value: 0.7893
临界值:
1%: -3.4656
5%: -2.8770
10%: -2.5751
是否平稳: 否
p-value 0.7893,远大于0.05,不能拒绝原假设。序列非平稳。
再看一个平稳序列的例子:
# 模拟白噪声(平稳)
white_noise = np.random.randn(200)
result = adfuller(white_noise, autolag='AIC')
print(f'p-value: {result[1]:.4f}')
print(f'是否平稳: {"是" if result[1] < 0.05 else "否"}')
输出:
p-value: 0.0000
是否平稳: 是
p-value接近0,拒绝原假设,序列平稳。
4.3 p-value解读
p-value是ADF检验里最容易让人迷惑的地方。我见过不少新手把p-value理解反了。
记住一句话:p-value越小,越平稳。
| p-value范围 | 结论 | 说明 |
|---|---|---|
| p < 0.01 | 在1%水平上显著平稳 | 非常强的平稳证据 |
| 0.01 ≤ p < 0.05 | 在5%水平上显著平稳 | 一般可接受 |
| 0.05 ≤ p < 0.10 | 在10%水平上显著平稳 | 边缘情况,需谨慎 |
| p ≥ 0.10 | 非平稳 | 不能拒绝原假设 |
举个例子:p=0.03,意味着在原假设为真的情况下,观察到当前检验统计量的概率只有3%。这个概率很小,所以我们拒绝原假设,认为序列平稳。
反过来,p=0.78,意味着有78%的概率观察到这样的结果。概率太大,不能拒绝原假设。
4.4 常见陷阱
ADF检验看着简单,坑其实不少。我一个个说:
陷阱一:滞后阶数选择不当
滞后阶数太少,残差可能有自相关。滞后阶数太多,检验功效下降。我一般用AIC或BIC自动选择,然后手动检查残差是否白噪声。
陷阱二:趋势项和截距项的选择
ADF检验有三种形式:
- 无截距无趋势:序列均值为0
- 有截距无趋势:序列均值非0
- 有截距有趋势:序列有线性趋势
选错了,检验结果可能完全相反。我习惯先画图看看序列有没有明显趋势,再决定用哪种形式。
陷阱三:结构性断点
如果序列在某个时间点发生了结构性变化(比如政策变化、市场改革),ADF检验可能误判。这时候要用Zivot-Andrews检验或者Perron检验。
陷阱四:样本量太小
ADF检验在小样本下功效很低。少于50个观测值,检验结果基本不可信。我一般要求至少100个数据点。
陷阱五:忽略多重比较
做协整配对时,要检验几十上百对序列。每对都做ADF,多重比较问题就来了。p=0.05意味着每20次检验就有1次假阳性。我一般用Bonferroni校正或者FDR控制。
- ADF检验原假设是存在单位根(非平稳)
- p-value越小越平稳,一般以0.05为界
- 滞后阶数、趋势项选择、样本量都会影响结果
- 多重比较时记得做校正
最后说一句:ADF检验不是万能的。它只能检测单位根,不能检测其他类型的非平稳性(比如季节性、异方差性)。实际应用中,我通常会把ADF和KPSS检验结合起来用,互相验证。
嗯,平稳性检验这块就这些。代码写起来简单,但背后的逻辑和陷阱值得多花点时间琢磨。