时间序列平稳性检验:从ADF到KPSS的双重验证策略

📅 2026/7/14 12:28:49
时间序列平稳性检验:从ADF到KPSS的双重验证策略
1. 时间序列平稳性的核心概念我第一次接触时间序列分析时被平稳性这个概念折磨得不轻。直到有次分析销售数据发现预测结果总是离谱前辈才点醒我先检查平稳性那什么是平稳性呢想象你每天记录体重如果体重始终在70kg上下小幅波动均值稳定波动幅度也差不多方差稳定今天和昨天的体重关系与上周今天和上周昨天的关系类似协方差稳定这就是平稳序列。严格来说平稳时间序列需要满足三个条件均值稳定序列的期望值不随时间变化。比如零售店的日销售额没有明显的增长或下降趋势方差稳定数据的波动幅度保持恒定。股票价格如果波动越来越大就不满足这个条件自协方差稳定相隔相同时间间隔的数据点之间的关系不变。比如月度数据中今年1月和2月的关系与去年1月和2月的关系应该相似为什么平稳性这么重要我吃过亏才明白大多数时间序列模型ARIMA等都假设数据是平稳的。用非平稳数据建模就像在流沙上盖房子——模型参数会漂移预测结果根本不可靠。有次我用非平稳的电商流量数据直接建模预测下周流量会是负值被同事笑话了好久。2. ADF检验的实战指南2.1 ADF检验的原理剖析ADF检验全称Augmented Dickey-Fuller检验是检测单位根的经典方法。什么是单位根可以理解为序列中的记忆效应——当前值严重依赖前值导致冲击的影响永不消退。好比醉酒走路每一步都受上一步影响最终轨迹无法预测。ADF检验的核心是以下回归方程Δy_t α βt γy_{t-1} δ1Δy_{t-1} ... δpΔy_{t-p} ε_t其中γ就是关键参数原假设H0γ0存在单位根序列非平稳备择假设H1γ0不存在单位根序列平稳检验统计量是γ的估计值除以其标准误。这个值越负越倾向于拒绝原假设。我在金融数据分析时常用三个置信水平1%、5%、10%对应不同的临界值。2.2 Python实现步骤实际应用中我推荐使用Python的statsmodels库。以下是完整代码示例import pandas as pd from statsmodels.tsa.stattools import adfuller import matplotlib.pyplot as plt # 读取数据示例为模拟的销售数据 data pd.read_csv(sales_data.csv, parse_dates[date], index_coldate) # 可视化观察 plt.figure(figsize(12,6)) plt.plot(data[sales]) plt.title(Daily Sales Trend) plt.grid(True) plt.show() # 执行ADF检验 result adfuller(data[sales], autolagAIC) # 自动选择最佳滞后阶数 print(fADF Statistic: {result[0]:.4f}) print(fp-value: {result[1]:.4f}) print(Critical Values:) for key, value in result[4].items(): print(f {key}: {value:.4f}) # 结果解读 if result[1] 0.05: print(拒绝原假设序列平稳) else: print(无法拒绝原假设序列非平稳)几个实用技巧滞后阶数选择建议用autolagAIC自动确定比固定阶数更可靠趋势项处理如果数据有明显趋势添加参数regressionct包含常数项和趋势项季节性数据先做季节性差分再用ADF检验2.3 结果解读的常见误区新手常犯的错误是只看p值。我有三点经验临界值对比当检验统计量小于1%临界值可以99%确信序列平稳结合图形判断即使ADF显示平稳如果图形有明显趋势可能需要差分样本量影响小样本容易得出假平稳结论建议至少50个以上数据点曾经分析过一组用户活跃数据ADF的p值是0.06略高于0.05但图形显示均值稳定。后来扩大样本量重新检验确认确实是平稳序列。3. KPSS检验的深度解析3.1 与ADF检验的哲学差异KPSS检验(Kwiatkowski-Phillips-Schmidt-Shin Test)与ADF检验的假设正好相反原假设H0序列是趋势平稳的或水平平稳备择假设H1序列存在单位根这种互补性很有意思ADF说假设你有病证明你没病KPSS说假设你健康证明你有病。就像医生用不同检查手段交叉验证病情。KPSS检验的统计量构造也不同它基于残差的累积和KPSS \frac{1}{T^2} \sum_{t1}^T \frac{S_t^2}{s^2(l)}其中S_t是部分和s²(l)是长期方差估计。3.2 实际应用演示继续用Python实现KPSS检验from statsmodels.tsa.stattools import kpss # 执行KPSS检验 result_kpss kpss(data[sales], regressionc) # c表示水平平稳ct表示趋势平稳 print(fKPSS Statistic: {result_kpss[0]:.4f}) print(fp-value: {result_kpss[1]:.4f}) print(Critical Values:) for key, value in result_kpss[3].items(): print(f {key}: {value:.4f}) # 结果解读 if result_kpss[1] 0.05: print(拒绝原假设序列非平稳) else: print(无法拒绝原假设序列平稳)注意点regression参数c检验水平平稳ct检验趋势平稳选错会导致误判带宽选择默认使用Andrews带宽对长期方差估计影响很大与ADF结合当两者结论矛盾时说明可能是趋势平稳或差分平稳3.3 检验结果冲突怎么办我在分析GDP数据时遇到过典型冲突ADF检验p0.12 → 不拒绝非平稳KPSS检验p0.03 → 拒绝平稳这种矛盾其实揭示了趋势平稳性的存在。解决方案是先对数据去趋势用线性回归拟合趋势线并减去对残差再做ADF检验如果此时ADF显示平稳说明原序列是趋势平稳的具体操作from sklearn.linear_model import LinearRegression import numpy as np # 提取时间趋势项 X np.arange(len(data)).reshape(-1, 1) y data[sales].values model LinearRegression().fit(X, y) trend model.predict(X) # 去趋势 detrended y - trend # 检验去趋势后的序列 result_adf_detrended adfuller(detrended) print(f去趋势后ADF p值: {result_adf_detrended[1]:.4f})4. 双重检验的综合策略4.1 四种典型情况分析根据ADF和KPSS的组合结果可以得出更精确的判断案例ADF结果KPSS结果结论处理方法1非平稳非平稳真实非平稳需要差分2平稳平稳严格平稳直接建模3非平稳平稳趋势平稳去除趋势4平稳非平稳差分平稳使用差分最棘手的是案例3和案例4。我总结的决策流程先看ADF如果拒绝非平稳进入步骤2否则直接差分看KPSS如果KPSS也接受平稳则是严格平稳如果KPSS拒绝可能是差分平稳对差分后序列重新检验确认是否转为平稳4.2 金融时间序列的完整案例以某股票日收盘价为例演示完整分析流程# 获取股票数据 import yfinance as yf stock yf.download(AAPL, start2020-01-01, end2023-12-31) # 原始序列检验 adf_result adfuller(stock[Close]) kpss_result kpss(stock[Close]) print(f原始序列 - ADF p值: {adf_result[1]:.4f}, KPSS p值: {kpss_result[1]:.4f}) # 情况3处理尝试去趋势 X np.arange(len(stock)).reshape(-1, 1) y stock[Close].values model LinearRegression().fit(X, y) stock[Detrended] y - model.predict(X) # 检验去趋势后序列 adf_detrended adfuller(stock[Detrended]) print(f去趋势后 - ADF p值: {adf_detrended[1]:.4f}) # 情况4处理尝试一阶差分 stock[Diff] stock[Close].diff().dropna() adf_diff adfuller(stock[Diff]) kpss_diff kpss(stock[Diff]) print(f一阶差分 - ADF p值: {adf_diff[1]:.4f}, KPSS p值: {kpss_diff[1]:.4f})实际输出可能显示原始序列ADF p0.98非平稳KPSS p0.01非平稳→ 案例1一阶差分后ADF p0.01平稳KPSS p0.10平稳→ 案例2 说明该股票价格是一阶差分平稳的适合用ARIMA(1,1,1)等模型。4.3 最佳实践建议根据我的项目经验推荐以下工作流可视化先行绘制序列图、ACF/PACF图形成初步判断双重检验同时进行ADF和KPSS检验记录p值和检验统计量矛盾解析ADF平稳但KPSS非平稳 → 尝试差分ADF非平稳但KPSS平稳 → 尝试去趋势转换验证对转换后数据重新检验直到获得一致结论模型适配根据最终平稳类型选择建模方法严格平稳ARMA趋势平稳ARIMA趋势外生变量差分平稳ARIMA仍不平稳考虑季节性差分或更复杂转换记住没有放之四海而皆准的方法。有次分析气象数据常规方法都无效最后发现需要用Box-Cox变换处理异方差后才显现平稳性。