基于 ARIMA 模型的非平稳时间序列预测
摘要:本文主要记录统计学课程中 ARIMA(p,d,q) 模型的参数估计、差分处理与白噪声检验流程。文末嵌入了一个可交互 demo,可以实时拖动 p/d/q 看拟合与预测曲线的变化。
1. 理论基础
时间序列分析的核心在于提取数据中的趋势 (Trend) 与季节性 (Seasonality)。对于非平稳序列,我们需要通过差分消除单位根。ARIMA(p, d, q) 模型可以写成:
其中 为滞后算子, 是 AR 多项式, 是 MA 多项式,。
- p:自回归阶数(AR)
- d:差分阶数(去趋势)
- q:移动平均阶数(MA)
2. 数据预处理 (R Language)
首先加载必要的库,并进行单位根检验 (ADF Test):
library(tseries)
library(forecast)
data <- read.csv("data.csv")
ts_data <- ts(data$value, frequency = 12)
# ADF 检验:H0 = 存在单位根(序列非平稳)
adf.test(ts_data)
# p-value > 0.05,表明序列不平稳,需要进行一阶差分
diff_data <- diff(ts_data)
plot(diff_data, main = "一阶差分后序列", ylab = "Δ x_t")
adf.test(diff_data)
# 若 p-value < 0.05,接受平稳假设,取 d = 1
3. 定阶:ACF / PACF
差分到平稳后,用 ACF 与 PACF 图粗估 与 :
par(mfrow = c(1, 2))
acf(diff_data, lag.max = 40, main = "ACF")
pacf(diff_data, lag.max = 40, main = "PACF")
经验规则:
| 模型 | ACF | PACF |
|---|---|---|
| AR(p) | 拖尾 | p 阶截尾 |
| MA(q) | q 阶截尾 | 拖尾 |
| ARMA(p, q) | 拖尾 | 拖尾 |
当两边都拖尾,交给 auto.arima 用 AIC/BIC 网格搜索即可。
4. 参数估计与诊断
fit <- Arima(ts_data, order = c(1, 1, 1))
summary(fit)
# 残差白噪声检验
Box.test(residuals(fit), lag = 12, type = "Ljung-Box")
# p-value 越大越好(不能拒绝残差是白噪声)
checkresiduals(fit)
5. 预测
fc <- forecast(fit, h = 12)
autoplot(fc) +
ggtitle("ARIMA(1,1,1) — 12 步预测") +
theme_minimal()
6. 交互 demo — 自己拖 p / d / q 看看
下面是一个在浏览器里实时拟合的 demo。拖动滑块可以看到:
- p 越大,AR 部分越吃数据的趋势惯性
- d 决定差分几次,过度差分会吃掉信号
- q 越大,MA 部分越能平滑残差
ARIMA(p, d, q) Pull the sliders — fit recomputes live.
Observed
Fitted
Forecast (12)
7. 踩坑总结
- 过度差分:d = 2 往往导致残差自相关消失得太干净但方差变大,预测区间拉宽到没意义。
- 季节性没处理:月度数据建议直接上
SARIMA(p,d,q)(P,D,Q)s,裸 ARIMA 会把 12 月的 spike 当噪声。 - auto.arima 不是银弹:它的 stepwise 搜索会卡在局部 AIC 最优,建议
stepwise = FALSE, approximation = FALSE做一次全局搜索确认。
参考
- Cryer & Chan, Time Series Analysis: With Applications in R (2nd ed.)
- Hyndman & Athanasopoulos, Forecasting: Principles and Practice (3rd ed.), otexts.com/fpp3