Page QiView

时间序列:ARIMA 与 SARIMA 从原理到实战

时间序列:ARIMA 与 SARIMA 从原理到实战

1. 先回答一个问题:ARIMA 解决什么

ARIMA 不是“万能预测器”,它专门处理单变量时间序列里由自相关结构驱动的可预测成分。
核心思想是把序列写成“差分后的平稳过程 + 误差修正项”。

当你需要:

  1. 解释性强于黑箱精度;
  2. 样本量中小、特征工程有限;
  3. 业务需要可审计的模型诊断;

ARIMA 往往是第一选择。

2. 模型结构与数学形式

ARIMA$(p,d,q)$:

$$ \phi(B)(1-B)^d y_t = c + \theta(B)\varepsilon_t $$

其中:

  1. $p$ 是自回归阶数;
  2. $d$ 是差分阶数;
  3. $q$ 是移动平均阶数;
  4. $B$ 是滞后算子。

若存在季节项,使用 SARIMA$(p,d,q)\times(P,D,Q)_s$:

$$ \Phi(B^s)\phi(B)(1-B)^d(1-B^s)^D y_t = c + \Theta(B^s)\theta(B)\varepsilon_t $$

3. 建模流程(原则优先)

  1. 先画序列图与季节分解,不要直接网格搜索。
  2. 通过 ADF/KPSS 判断是否需要差分。
  3. 用 ACF/PACF 给 $p,q,P,Q$ 初值。
  4. 用 AIC/BIC 做候选比较。
  5. 对残差做白噪声检验(Ljung-Box)。

4. Python 参考实现

import pandas as pd
from statsmodels.tsa.statespace.sarimax import SARIMAX
from statsmodels.stats.diagnostic import acorr_ljungbox

# y: DatetimeIndex 的单变量序列
train = y.iloc[:-24]
test = y.iloc[-24:]

model = SARIMAX(
    train,
    order=(1, 1, 1),
    seasonal_order=(1, 1, 1, 12),
    enforce_stationarity=False,
    enforce_invertibility=False,
)
res = model.fit(disp=False)

pred = res.get_forecast(steps=len(test)).predicted_mean

lb = acorr_ljungbox(res.resid.dropna(), lags=[12], return_df=True)
print(lb)

5. 常见误区

  1. 过度差分:把可预测信号差掉。
  2. 只看训练集拟合优度,不做滚动预测。
  3. 残差有显著自相关却直接上线。
  4. 忽略结构突变(政策、疫情、价格机制变化)。

6. 实务建议

  1. 把 ARIMA 作为可解释基线,再与树模型/深度模型对比。
  2. 业务里优先报告区间预测,不只报点预测。
  3. 当残差长期偏态或厚尾,考虑 GARCH 或状态空间扩展。

ARIMA 的价值不只是“预测值”,而是它把时间依赖结构显式化,便于你定位误差来源并迭代系统。