ADF检验的p值小于0.05,且ADF统计量小于临界值(比如-3.43),才能判定序列平稳;反过来,p值大于0.05,或者序列明显带趋势/季节性,那就得考虑差分。通常一阶或二阶就够了,超过二阶容易过差分,得不偿失。

怎么判断一个序列是否需要差分
关键看 adfuller 返回的 p-value——小于0.05才算平稳,大于0.05就得差分。但别只盯着p值,还要对照 adf 统计量是否小于临界值(比如-3.43),否则容易误判。一个常见陷阱是:原始序列明明有明显的趋势或季节性,adfuller 却返回p=0.07,这时候不能硬扛,该差分还是得差分。
实操建议:
- 先画
plot()观察趋势和方差是否随时间变化——突增、缓升、周期震荡都是非平稳的信号。 - 用
adfuller(series, autolag="AIC"),别省掉autolag参数,否则滞后阶数选不准,检验效力会打折扣。 - 如果一阶差分后仍不平稳(p > 0.05),再试二阶,但超过二阶就得警惕——可能过差分导致噪声放大、模型失真。
Statsmodels里怎么正确做ADF检验
adfuller 默认只检验无常数项、无趋势项的单位根,但现实数据大多带漂移或趋势,直接调用容易漏检。必须根据序列形态手动指定 regression 参数。
实操建议:
- 纯随机游走(均值不变、无趋势)→ 用默认
regression="c"(含截距)。 - 有线性趋势(如逐年增长)→ 改成
regression="ct"(含截距 + 时间趋势项)。 - 季节性强的数据(如月度销售)→ 先用
seasonal_decompose拆解,再对残差做ADF,别直接对原序列硬上。 - 检验前务必 drop 掉 NaN:差分后头几个值是NaN,
adfuller遇到会报ValueError: array must not contain infs or NaNs。
ARIMA建模时d参数怎么定,和差分操作怎么对齐
ARIMA(p, d, q) 中的 d 必须等于你实际做的差分阶数,而且差分操作必须在拟合前完成——Statsmodels不会在内部自动帮你差分原始序列。很多人把 d=1 和原始序列直接喂给 ARIMA,结果模型拟合的是差分后序列,预测时却反向还原错位,导致结果全偏。
实操建议:
- 先用
series.diff(d).dropna()得到平稳序列,再用它跑adfuller验证。 d取值后,建模时传入原始序列 +d参数:ARIMA(series, order=(p, d, q)),内部会按需差分。- 预测后用
model.forecast(steps=10)得到的是差分域结果;要还原到原始尺度,得用model.get_forecast().predicted_mean配合series.iloc[-1]手动累加(尤其d=1时)。 - 别用
diff().diff()做二阶差分——它会把索引搞乱,改用series.diff(2)。
差分后建模效果差,可能是这几点没注意
差分只是手段,不是万能解。很多情况下,差分完ADF过了,但ARIMA拟合残差仍有自相关,说明差分没解决根本问题——比如季节性未剥离、外生变量缺失、或波动率时变(需GARCH)。
实操建议:
- 画
plot_acf/plot_pacf看差分后序列:如果滞后12处还有显著峰,大概率是残留季节性,得考虑SARIMAX而非普通ARIMA。 - 检查残差是否异方差:用
plot(series.diff().std())看标准差是否随时间跳变,跳变明显就别硬上ARIMA,试试对数变换或ARCH类模型。 - 差分会丢失首部信息,样本量变少,小数据集(比如少于50个点)慎用高阶差分,否则信息损失过大,模型反而更差。
说到底,差分不是黑箱开关,它改变的是序列的生成机制。同一个 d 值,在不同数据上意义可能完全不同——关键是你差分之后,是否还相信这个序列的未来是由它的过去线性决定的。