在之前的专栏中我们用ARIMA的方法做了时间序列的趋势性预测。
不过我们经常还会遇到一种情况,即某些时间序列中存在明显的周期性变化,这种周期是由于季节性变化(季度、月度等)引起的。
如下图所示,为1949年到1960年每月国际航空公司的乘客人数。从中可以看到明显的季节性,该周期为12个月。
其中包含了季节性和趋势性
一种适用于描述这类序列的模型称作季节时间序列模型(SARIMA, seasonal ARIMA model),也叫乘积ARIMA模型,因为模型的形式是以相乘的形式表示。
有关于SARIMA的理论知识这里也不展开了,需要了解基础原理的可以看这里(这个文档是付费的,不过免费预览的那段也足够用了)。
假设你已经了解了模型的基本形式,现在开始编程。编程答题思路与ARIMA相同,不过细节处有颇多不同。
1.加载试验数据与参数设置
%% 1.加载数据
load('Data_Airline.mat') %加载航空公司数据
data = Data(:); %转为列向量
S = 12; %季节性序列变化周期,12个月
figflag = 'on'; %打开画图
step = 48; %预测步数
2.确定季节性与非季节性差分数
与ARIMA模型一样,使用SARIMA模型也要求数据平稳。不同的是SARIMA的差分项有两个,分别是季节性差分与非季节性差分。通常季节性差分经过一次即可,非季节性差分通常在0~3之间。
使用下述代码将原始序列进行差分计算,需要注意差分后的序列长度将会缩短。
%% 2.确定季节性与非季节性差分数,D取默认值1,d从0至3循环,平稳后停止
for d = 0:3
D1 = LagOp({1 -1},'Lags',[0,d]); %非季节差分项的滞后算子
D12 = LagOp({1 -1},'Lags',[0,1*S]); %季节差分项的滞后算子
D = D1*D12; %相乘
dY = filter(D,data); %对原数据进行差分运算
if(getStatAdfKpss(dY)) %数据平稳
disp(['非季节性差分数为',num2str(d),',季节性差分数为1']);
break;
end
end
上述代码中的getStatAdfKpss为检验数据是否已经平稳的自定义函数,当函数返回1时说明数据已经平稳。
3.确定SARIMA模型阶数
这个步骤中需要确定的阶数有四个:AR阶数p,MA阶数q,SAR阶数P,SMA阶数Q。这里就不贴PCA和FPCA定阶的方法了,而是直接用简单粗暴的暴力定阶(基于AICBIC准则的方法)。
%% 3.确定阶数ARlags,MALags,SARLags,SMALags
max_ar = 3; %
max_ma = 3;
max_sar = 3;
max_sma = 3;
try
[AR_Order,MA_Order,SAR_Order,SMA_Order] = SARMA_Order_Select(dY,max_ar,max_ma,max_sar,max_sma,S,d); %自动定阶
catch ME %捕捉错误信息
msgtext = ME.message;
if (strcmp(ME.identifier,'econ:arima:estimate:InvalidVarianceModel'))
msgtext = [msgtext,' ','无法进行arima模型估计,这可能是由于用于训练的数据长度较小,而要进行拟合的阶数较高导致的,请尝试减小max_ar,max_ma,max_sar,max_sma的值'];
end
msgbox(msgtext, '错误')
end
disp(['ARlags=',num2str(AR_Order),',MALags=',num2str(MA_Order),',SARLags=',num2str(SAR_Order),',SMALags=',num2str(SMA_Order)]);
SARMA_Order_Select是我自己写的一个函数,只需要输入信号、最大p值、最大q值、最大P、最大Q、序列周期和差分阶数就可以得到推荐p、q、P、Q。
运行结果为:
ARlags=1,MALags=1,SARLags=1,SMALags=1
即p=1,q=1,P=1,Q=1
4.残差检验
为了确保确定的阶数合适,还需要进行残差检验。残差即原始信号减掉模型拟合出的信号后的残余信号。如果残差是随机正态分布的、不自相关的,这说明残差是一段白噪声信号,也就说明有用的信号已经都被提取到ARMA模型中了。
下述代码中的creatSARIMA是笔者专门写的构建模型的函数,这里的处理方式的不同就是ARMA与SARIMA方法的众多差别的体现。总体来说SARIMA的是更复杂的。
Mdl = creatSARIMA(AR_Order,MA_Order,SAR_Order,SMA_Order,S,d); %创建SARIMA模型
try
EstMdl = estimate(Mdl,data);
catch ME %捕捉错误信息
msgtext = ME.message;
if (strcmp(ME.identifier,'econ:arima:estimate:InvalidVarianceModel'))
msgtext = [msgtext,' ','无法进行arima模型估计,这可能是由于用于训练的数据长度较小,而要进行拟合的阶数较高导致的,请尝试减小max_ar和max_ma的值']
end
msgbox(msgtext, '错误')
return
end
[res,~,logL] = infer(EstMdl,data); %res即残差
stdr = res/sqrt(EstMdl.Variance);
figure('Name','残差检验','Visible','on')
subplot(2,3,1)
plot(stdr)
title('Standardized Residuals')
subplot(2,3,2)
histogram(stdr,10)
title('Standardized Residuals')
subplot(2,3,3)
autocorr(stdr)
subplot(2,3,4)
parcorr(stdr)
subplot(2,3,5)
qqplot(stdr)
残差检验
上图为残差检验的结果图。Standardized Residuals是查看残差是否接近正态分布,理想的残差要接近正态分布;ACF和PACF检验残差的自相关和偏自相关,理想的结果应该在图中不存在超出蓝线的点;最后一张QQ图是检验残差是否接近正太分布的,理想的结果中蓝点应该靠近红线。
除了上述图像检验方法,还可以通过Durbin-Watson对相关性进行检验:
% Durbin-Watson 统计是计量经济学分析中最常用的自相关度量
diffRes0 = diff(res);
SSE0 = res'*res;
DW0 = (diffRes0'*diffRes0)/SSE0 % Durbin-Watson statistic,该值接近2,则可以认为序列不存在一阶相关性。
运算结果为1.9887,这个值越接近2越说明残差不存在一阶相关性。
上述检验可以证明,残差接近正态分布,且相互独立,可以认为ARMA建模符合要求。
5.预测
[forData,YMSE] = forecast(EstMdl,step,data); %matlab2018及以下版本写为Predict_Y = forecast(EstMdl,step,'Y0',Y); matlab2019写为Predict_Y = forecast(EstMdl,step,Y);
lower = forData - 1.96*sqrt(YMSE); %95置信区间下限
upper = forData + 1.96*sqrt(YMSE); %95置信区间上限
figure('Visible','on')
plot(data,'Color',[.7,.7,.7]);
hold on
h1 = plot(length(data):length(data)+step,[data(end);lower],'r:','LineWidth',2);
plot(length(data):length(data)+step,[data(end);upper],'r:','LineWidth',2)
h2 = plot(length(data):length(data)+step,[data(end);forData],'k','LineWidth',2);
legend([h1 h2],'95% 置信区间','预测值',...
'Location','NorthWest')
title('Forecast')
hold off
直接上结果:
上图中灰线为用来训练的数据,黑线为未来值的预测,红线为95%置信区间上下限。也就是说未来真实值有95%的概率落在这个范围内。
6.封装
上述整个过程可以封装成一个函数,如下:
function [forData,lower,upper] = Fun_SARIMA_Forecast(data,step,max_ar,max_ma,max_sar,max_sma,S,figflag)
% 使用SARIMA进行预测的函数,可以直接调用,非季节差分阶数自动确定。p,q,P,Q自动确定
% 输入:
% data为待预测数据,一维数据,使用SARIMA时,该数据长度至少为10+S,S为周期长度,但是达到10+S之后仍然可能会报错,可能是由数据的差分处理使得目标数据长度变短导致的。
% step为拟预测步数
% max_ar为AR模型搜寻的最大阶数 建议不大于3
% max_ma为MA模型搜寻的最大阶数 建议不大于3
% max_sar为SAR模型搜寻的最大阶数 建议不大于3
% max_sms为SMA模型搜寻的最大阶数 建议不大于3
% S为季节性周期
% figflag 为画图标志位,'on'为画图,'off'为不画
% 输出:
% forData为预测结果,其长度等于step
% lower为预测结果的95%置信下限值
% upper为预测结果的95%置信上限值
直接调用就可以出结果。
获取文章中全部源码,可以点击下述链接获取:
SARIMA时间序列预测图形界面版软件(完整版) | 工具箱文档
参考: