12.4 自回归积分滑动平均模型¶
小率已经会看趋势、季节和差分了。现在他想把这些判断拼成一个能预测未来销量的模型。均哥拿出四张卡片:AR、I、MA、季节。
ARIMA 这个名字好吓人,是不是很复杂?
拆开就不吓人:AR 看过去的值,I 先差分,MA 看过去的预测误差。
12.4.1 三个字母各管一件事¶
ARIMA 是 Autoregressive Integrated Moving Average 的缩写。
ARIMA\((p,d,q)\) 中:
- \(p\):AR 阶数,使用多少个过去的观测值。
- \(d\):差分次数,让序列更接近平稳。
- \(q\):MA 阶数,使用多少个过去的预测误差。
一个简单的 AR(1) 可以写作:
\[
y_t = c + \phi_1 y_{t-1} + \varepsilon_t
\]
如果先做一次差分,再对差分后的序列建 ARMA 模型,就进入 ARIMA 的思路。
12.4.2 ACF 和 PACF 帮我们猜阶数¶
ACF 和 PACF 不是万能答案,但能给定阶提供线索:
| 图形线索 | 常见提示 |
|---|---|
| ACF 缓慢衰减 | 可能还没平稳,需要差分 |
| PACF 在某阶后明显截尾 | 可能需要 AR 项 |
| ACF 在某阶后明显截尾 | 可能需要 MA 项 |
| 季节滞后处有峰 | 可能需要季节项 |
定阶不要只靠肉眼
先用图形提出候选模型,再用 AIC/BIC、残差自相关和预测回测来筛选。
12.4.3 季节 ARIMA 把周期也放进模型¶
如果奶茶销量有周周期或月度数据有年周期,可以用 SARIMA:
\[
\operatorname{SARIMA}(p,d,q)(P,D,Q)_s
\]
其中 \(s\) 是周期长度。月度数据的年周期常取 \(s=12\),周数据若有年度周期可取 \(s=52\)。
import numpy as np
import pandas as pd
from statsmodels.tsa.statespace.sarimax import SARIMAX
rng = np.random.default_rng(12)
dates = pd.date_range("2018-01-01", periods=96, freq="MS")
t = np.arange(len(dates))
y = pd.Series(
200 + 1.8 * t + 18 * np.sin(2 * np.pi * t / 12) + rng.normal(0, 5, len(t)),
index=dates,
name="月销量",
)
model = SARIMAX(
y,
order=(1, 1, 1),
seasonal_order=(0, 1, 1, 12),
enforce_stationarity=False,
enforce_invertibility=False,
)
fit = model.fit(disp=False)
print("AIC:", round(fit.aic, 2))
print(fit.forecast(6).round(1))
完整脚本见:
12.4.4 残差检查决定模型能不能交卷¶
拟合完 ARIMA 之后,别只看预测线。残差应该像白噪声:没有明显趋势、没有强自相关、没有系统性漏掉的周期。
ARIMA 不是自动预测机
阶数选得漂亮,不代表预测一定好。时间序列模型必须做滚动回测,尤其不能用未来数据参与训练。
小率的笔记本
ARIMA = AR + I + MA。
AR 看过去的值,I 负责差分,MA 看过去的误差。
季节明显时,考虑 SARIMA。
模型拟合后一定要查残差和回测表现。

