跳转至

12.3   平稳性与差分

小率画了两条销量线。一条在固定水平附近上下晃,另一条一路往上走。两条都在波动,但均哥只说第一条“更适合直接建模型”。

图 12.3.1 小率比较稳定波动和一路漂移的序列

都是折线,为什么有的可以直接建模,有的要先处理?
很多时间序列模型喜欢“规律不随时间改变”的数据。均值一直漂,模型就很难分清趋势和随机波动。

12.3.1   平稳不是不动,而是波动规则稳定

弱平稳 (Weak Stationarity) 常看三件事:

  • 均值大致稳定:没有持续上升或下降。
  • 方差大致稳定:波动幅度不随时间明显变大或变小。
  • 自协方差只和间隔有关:相隔 1 天、7 天的关系稳定,不依赖具体是哪一天。

图 12.3.2 平稳、非平稳和差分后的对比

直觉上,平稳序列像“围着同一条水平线晃”;非平稳序列像“水平线自己也在移动”。

12.3.2   差分是在看变化量

一阶差分 (First Difference) 把原序列变成相邻两期的变化:

\[ \Delta y_t = y_t - y_{t-1} \]

如果原始销量从 120、126、131 变成差分 6、5,问题就从“销量有多高”变成“销量比上一期多了多少”。

季节差分 (Seasonal Difference) 则比较同一个周期位置:

\[ \Delta_s y_t = y_t - y_{t-s} \]

比如月度数据常取 \(s=12\),比较“今年 7 月”和“去年 7 月”。

差分也可能过头

差分太少,趋势还留在数据里;差分太多,原本有用的水平信息会被削弱。看图、看检验、看残差,要一起判断。

12.3.3   ADF 和 KPSS 是两盏不同的灯

常见检验有两类:

  • ADF 检验:原假设通常是“有单位根,非平稳”。
  • KPSS 检验:原假设通常是“平稳”。

它们的原假设方向相反,所以最好一起看。若 ADF 倾向拒绝非平稳、KPSS 不拒绝平稳,证据更一致。

import numpy as np
import pandas as pd
from statsmodels.tsa.stattools import adfuller, kpss

rng = np.random.default_rng(12)
steps = rng.normal(0, 1, 120)
random_walk = pd.Series(steps.cumsum(), name="随机游走")
diffed = random_walk.diff().dropna()

for name, series in [("原序列", random_walk), ("一阶差分", diffed)]:
    adf_p = adfuller(series)[1]
    kpss_p = kpss(series, regression="c", nlags="auto")[1]
    print(name, "ADF p值=", round(adf_p, 4), "KPSS p值=", round(kpss_p, 4))

完整脚本见:

docs/assets/scripts/ch12_time_series/03_stationarity/main.py

小率的笔记本

平稳不是“没有变化”,而是变化的规则比较稳定。
趋势会让序列非平稳,差分可以把“水平”改成“变化量”。
ADF 和 KPSS 要看原假设,不能只记一个 p 值口诀。