跳到主要内容

SARIMA 季节模型

一、直观理解:普通差分不够,还要“隔年/隔月对齐”​

很多序列不仅有趋势,还有固定周期:每月销售、每季度用电、每周访客。普通 ARIMA 的短期滞后难以干净地吃掉周期,残差 ACF 会在 s,2s,…s,2s,\ldots 处冒峰。

SARIMA 在 ARIMA 外再加季节差分与季节 AR/MA:

Φ(Bs)ϕ(B) (1−B)d(1−Bs)Dyt=c+Θ(Bs)θ(B)εt\Phi(B^s)\phi(B)\,(1-B)^d(1-B^s)^D y_t =c+\Theta(B^s)\theta(B)\varepsilon_t

记作 SARIMA(p,d,q)×(P,D,Q)s\mathrm{SARIMA}(p,d,q)\times(P,D,Q)_s。例如月数据 s=12s=12,先做 ∇12yt=yt−yt−12\nabla_{12}y_t=y_t-y_{t-12},再对结果建低阶模型,往往比硬造 AR(12) 干净得多。

二、适用场景与优缺点​

类型说明
适用场景明确周期 ss;季节幅度较稳定;样本至少覆盖多个完整季节(经验上 ≥3∼4\ge 3\sim 4 个周期更稳);需要可统计诊断的季节预测。
核心优点季节结构显式;参数比“超高阶 AR”更省;预测可保持季节形态;与指数平滑、Prophet 形成对照基线。
局限与缺点参数组合多,易过拟合;季节不稳或周期漂移时吃力;样本短时 D=1D=1 后有效长度骤减;多季节周期需更复杂扩展。

三、核心原理​

1. 季节差分​

(1−Bs)Dyt(1-B^s)^D y_t

D=1D=1 最常见,用于季节单位根/强季节水平。先普通差分还是先季节差分,可依据图形与检验,但务必避免双重过度差分。

2. 季节算子​

Φ(Bs)=1−Φ1Bs−⋯−ΦPBsP,Θ(Bs)=1+Θ1Bs+⋯+ΘQBsQ\Phi(B^s)=1-\Phi_1 B^s-\cdots-\Phi_P B^{sP},\quad \Theta(B^s)=1+\Theta_1 B^s+\cdots+\Theta_Q B^{sQ}

识别线索:季节差分后,在滞后 ss 附近看 ACF/PACF 的峰,以选择 P,QP,Q。

3. 与 Holt-Winters 的关系​

两者都能做季节预测。SARIMA 更偏随机过程与区间;三次指数平滑更偏状态平滑、调参直观。竞赛中宜两者都做,用测试误差说话。

四、定阶策略​

  1. 确定 ss(业务周期);
  2. 画原序列、∇y\nabla y、∇sy\nabla_s y、∇∇sy\nabla\nabla_s y;
  3. 选最小的 (d,D)(d,D) 使训练期大致平稳;
  4. p,q,P,Q∈{0,1,2}p,q,P,Q\in\{0,1,2\} 小网格 + AIC/BIC;
  5. 残差 ACF 在 ss 处应无明显峰;
  6. 训练期外对比:季节朴素 y^t+h=yt+h−s\hat y_{t+h}=y_{t+h-s}、Holt-Winters、非季节 ARIMA。

样本很短时,优先 P,D,Q≤1P,D,Q\le 1,防止参数爆炸。

五、MATLAB 示例​

%% 构造月度季节序列并拟合 SARIMA
rng(11);
s = 12; n = 144; % 12 年
t = (1:n)';
season = 10*sin(2*pi*t/s);
trend = 0.05*t;
y = 50 + trend + season + cumsum(0.2*randn(n,1));

T0 = 120; % 10 年训练,2 年测试
yTrain = y(1:T0); yTest = y(T0+1:end);

figure;
subplot(2,1,1); plot(yTrain); title("训练序列");
subplot(2,1,2); autocorr(diff(yTrain), 40); title("一阶差分 ACF");

%% 推荐写法:直接定义 SARIMA 结构并估计
% 常见航空乘客型:(0,1,1)x(0,1,1)_12
md = arima("Constant",NaN, ...
"D",1, "Seasonality",s, ...
"MALags",1, "SMALags",s);
est = estimate(md, yTrain, "Display","off");
summarize(est);

% 若需小网格比较,可再试 (1,1,1)x(0,1,1)_s 等
md2 = arima("Constant",NaN, "ARLags",1, "D",1, "MALags",1, ...
"Seasonality",s, "SMALags",s);
est2 = estimate(md2, yTrain, "Display","off");
[~,~,logL1] = infer(est, yTrain);
[~,~,logL2] = infer(est2, yTrain);
fprintf("模型1 AIC近似=%.2f, 模型2 AIC近似=%.2f\n", ...
-2*logL1+2*4, -2*logL2+2*5);
% 下面继续用 est 做预测;实务中选 AIC/测试误差更优者
% est = est2;

res = infer(est, yTrain);
figure; autocorr(res,40); title("SARIMA 残差 ACF");
[hLB,pLB] = lbqtest(res,"Lags",[12 24]);
fprintf("LB p(12)=%.4f p(24)=%.4f\n", pLB(1), pLB(min(2,end)));

h = numel(yTest);
[yf,yMSE] = forecast(est, h, "Y0", yTrain);
rmse = sqrt(mean((yTest-yf).^2));

% 季节朴素基线
yf_s = yTrain(end-s+1:end);
yf_s = repmat(yf_s, ceil(h/s), 1); yf_s = yf_s(1:h);
rmse_s = sqrt(mean((yTest-yf_s).^2));
fprintf("测试 RMSE SARIMA=%.3f, 季节朴素=%.3f\n", rmse, rmse_s);

figure;
plot(T0+1:T0+h,yTest,"k"); hold on;
plot(T0+1:T0+h,yf,"r","LineWidth",1.2);
plot(T0+1:T0+h,yf_s,"b--");
legend("真实","SARIMA","季节朴素");

说明:不同 MATLAB 版本对季节差分 D 的接口细节可能略有差异。若 estimate 报错,可手动:

ySeas = yTrain(s+1:end) - yTrain(1:end-s);
est2 = estimate(arima(0,1,1), ySeas, "Display","off");

并在预测后还原季节差分与普通差分。论文中写清你采用的实现路径即可。

六、如何解释结果​

应报告:

  1. 周期 ss 的业务依据;
  2. (d,D)(d,D) 选择与差分前后图形;
  3. (p,q,P,Q)(p,q,P,Q) 网格及准则/测试误差;
  4. 残差 ACF 是否仍在季节滞后上泄漏;
  5. 与季节朴素、Holt-Winters 的对比;
  6. 预测图是否保持合理的峰谷相位;
  7. 样本覆盖的季节个数与不确定性。

七、常见误区​

1. 样本只有 1~2 个周期就上复杂 SARIMA​

季节参数估不稳,不如指数平滑或回归+季节哑变量。

2. 忘记与季节朴素比较​

很多题目里“去年同月”已经很强,模型必须证明增量价值。

3. 季节幅度明显变化仍用可加 SARIMA​

可先对数变换,或考虑可乘季节、局部季节模型。

4. 把所有滞后堆到 12​

高阶非季节 AR 常过拟合,优先季节算子。

5. 只看样本内拟合曲线贴合​

季节模型自由度高,必须训练期外验证。

八、小结​

SARIMA 的核心是:

在 ARIMA 框架中显式加入季节差分与季节 AR/MA,使周期模式进入模型结构而非残留在误差里。

它是月/季数据的标准统计武器。实战要点:定准 ss、少而精的阶数、残差季节峰检查,以及必须打败季节朴素基线。不要只看 R2R^2,要以训练期外 RMSE/MAE 与诊断图作为验收标准。