使用SARIMA做季节时间序列预测全流程(附MATLAB代码)

2023-11-12

在之前的专栏中我们用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)

v2-2428304cbb5a6a68e810a57ddddd0fa2_720w.jpg

残差检验

上图为残差检验的结果图。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代码说明文档(公开版) | 工具箱文档

SARIMA时间序列预测图形界面版软件(完整版) | 工具箱文档

参考:

MATLAB 文档中心 - MathWorks 中国

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

使用SARIMA做季节时间序列预测全流程(附MATLAB代码) 的相关文章

  • 如何在Matlab中绘制网络?

    我有一个矩阵AMatlab中的维数mx2每行包含两个节点的标签 显示网络中的直接链接 例如 如果网络有4矩阵的节点A可能A 1 2 1 3 2 1 2 4 3 2 4 1 4 2 其中第一行表示有一个链接来自1 to 2 第二行表示有一个链
  • 在 matlab 代码中使用 dll 文件

    我需要使用 Matlab 中由 dll 文件定义的函数 我有一个例子 那个家伙将 dll 转换为 mexw32 文件 但我知道我是如何做到这一点的 我尝试使用加载库但它没有创建任何文件 我怎样才能做到这一点 loadlibrary http
  • 如何使用Matlab将数据保存到Excel表格中?

    我想将数据以表格形式保存在 Excel 工作表中 它应该看起来像 Name Age R no Gpa Adnan 24 18 3 55 Ahmad 22 12 3 44 Usman 23 22 3 00 每次当我执行我的文件时类数据 m 下
  • Numpy 相当于 MATLAB 的 hist [重复]

    这个问题在这里已经有答案了 由于某种原因 Numpy 的 hist 总是返回比 MATLAB 的 hist 少 1 个 bin 例如在 MATLAB 中 x 1 2 2 2 1 4 4 2 3 3 3 3 Rep Val hist x un
  • FMINCON 的替代方案

    除了 fmincon 之外还有其他更快 更高效的求解器吗 我正在使用 fmincon 来解决特定问题 但对于中等大小的向量变量来说 我的内存不足 我也没有任何超级计算机或云计算选项可供使用 我知道任何替代解决方案仍然会耗尽内存 但我只是想看
  • 如何在 MATLAB 编译的应用程序中运行外部 .m 代码? [复制]

    这个问题在这里已经有答案了 我有一个 MATLAB 项目 我使用 MCC 对其进行编译以获得单个可执行文件 然后我想知道外部程序员是否可以在 exe 中执行他的一些 m 文件 而无需重新编译整个项目 重点是提供一个应用程序 其他开发人员可以
  • 将 kinect RGB 和深度值转换为 XYZ 坐标

    我正在寻找一种简单的方法将 kinect RGB 和深度值转换为 XYZ 坐标 使用 MATLAB 我的目标是一个输入为以下内容的函数 每个点的 RGB 和深度值Kinect相机 并输出 每个点的 x y 和 z 值 RGB 深度 RGB
  • MATLAB - 通过垂直连接子矩阵重新排列矩阵

    我在执行以下任务时遇到问题 假设一个 3x6 矩阵 A 0 2787 0 2948 0 4635 0 8388 0 0627 0 0435 0 6917 0 1185 0 3660 0 1867 0 2383 0 7577 0 6179 0
  • 在 Matlab 中保存 Kinect 深度图像?

    通过使用 Kinect 我可以获得深度图像 其中每个深度图像像素存储相机和物体之间的距离 以毫米为单位 现在我想保存它们以便以后使用 最好的推荐是什么 我正在考虑将深度图像保存为图像 jpg png等 然而 该值通常是从50毫米到10000
  • 轴标注问题

    通过运行我编写的以下 matlab 函数 可以互换图中的 x 轴和 y 轴 谁能告诉我问题出在哪里或者帮我解决它吗 预先感谢您的任何帮助 function axislabeling n x 1 1 n y 1 1 n z zeros n n
  • 如何从 matlab 调用 Qtproject?

    我在 matlab 中有一个函数可以写入一个 file txt 我在 qt 项目中使用它 So 当我使用 unix 获取要运行的 qt 编译可执行文件时 我有一个 Matlab 文件 但出现错误 代码 unix home matt Desk
  • 在矩阵中找到叉的最快方法

    定义 A i j 1 是十字的中点 如果元素A i 1 j 1A i 1 j 1A i j 1 1A i j 1 1 这些元素和中点一起形成矩阵 A 中的十字 其中 A 至少是一个 3 3 矩阵 并且i j 0 假设上图是 8 8 矩阵 A
  • 氡变换线检测

    我正在尝试检测灰度图像中的线条 为此 我在 MATLAB 中使用 Radon 变换 我的 m 文件的示例如下所示 我可以使用此代码检测多行 我还使用线条的移位和旋转属性来绘制线条 但是 我不明白在获取rho和theta值后如何获取检测线的起
  • 在 Pari-GP 中嵌套特定递归

    每个人 我最初在 Stackexchange 上发布了类似的问题 它已移至此处 可以在链接中找到 在 Matlab 中声明函数递归序列 https stackoverflow com questions 67146061 declaring
  • Blob 的簇生长

    考虑以下来自 Mathworks 的图像 我已经用标签标记了斑点 L num bwlabel I 如何迭代连接所有斑点 即从一个斑点开始 找到离它最近的一个 考虑最左边的两个斑点 可以从一个斑点的许多点绘制许多条线来连接到另一个斑点blob
  • 如何在matlab中使矩阵图平滑

    就像上图一样 怎样才能让画面更流畅呢 或者缩小y轴的范围 数据来自二维矩阵 然后我用plot data 请随意提出任何想法 平滑线条的一种方法涉及样本点之间数据的非线性插值 当你这样做时plot x y o http www mathwor
  • 在 MATLAB 中验证输入的最佳实践

    在验证 MATLAB 函数中的输入时 什么时候使用 inputParser 比使用断言更好 或者还有其他更好的工具可用吗 我个人发现使用 inputParser 不必要地复杂 对于 Matlab 始终需要检查 3 项内容 存在 类型和范围
  • 计算向量的导数

    我有以下函数 维维亚尼曲线 Phi t cos t 2 cos t sin t sin t 只需检查它是否有效 s linspace 0 T 1000 plot3 cos s 2 cos s sin s sin s 如何推导函数Phi 可能
  • MATLAB 问题中的 Parfor

    为什么我不能使用parfor在这段代码中 parfor i 1 r for j 1 N r xr j N r i 1 x i r j 1 end end 这是错误 错误 parfor 中的变量 xr 无法分类 请参阅 MATLAB 中的并行
  • MATLAB - 从目录读取文件?

    我希望从目录中读取文件并对每个文件迭代执行操作 此操作不需要更改文件 我知道我应该为此使用 for 循环 到目前为止我已经尝试过 FILES ls path to folder for i 1 size FILES 1 STRU pdbre

随机推荐

  • 华硕电脑怎么录屏?分享实用录制经验!

    华硕电脑怎么录屏呀 刚买的笔记本电脑 是华硕的 自我感觉挺好用的 但是不知道怎么录屏 最近刚好要录一个教程 怎么都找不到在哪里录制 有人能教教我吗 随着电脑技术的不断发展 人们越来越依赖电脑进行工作和娱乐 录屏功能作为电脑的一项重要功能 已
  • 华为OD机试 C++ 【报文重排序】

    题目 你手里有一堆乱七八糟的消息片段 每个片段后面都跟着一个数字 那个数字就像是每个片段的编号 你需要按照这些数字 将消息片段整合成一个完整的消息 并把那些数字扔掉 输入 第一行告诉你有几个消息片段 记作N 0 lt N 1000 第二行就
  • Axure rp9 学习笔记-进度笔记以及问题整理

    Axure rp9 学习笔记 进度笔记以及问题整理 4 15 iphone 原型设计 遇到问题 1 苹果手机左按键画的过程中没有弧度 corner 选项为灰 没法选 2 将绘制好的iphone 原型图设置成母版以后 却无法更改颜色 我们对M
  • Rust vs Go:常用语法对比(八)

    题目来自 Golang vs Rust Which Programming Language To Choose in 2023 1 141 Iterate in sequence over two lists Iterate in seq
  • 【LeetCode 热题 HOT 100-002】两数相加(python)

    题集链接 https leetcode cn problem list 2cktkvj 题目链接 https leetcode cn problems add two numbers favorite 2cktkvj 一 题目 二 代码 解
  • C# winform Panel 获取滚轮事件

    使用 Panel 做为控件容器时 设置 Panel AutoScroll true时 在适当的时候将会出现滚动条 但是只能通过拖动滚动条来调整滚动条的位置 如果想要用鼠标中间键来控制滚动条的位置 可以通过下面几步来完成 1 在构造函数中加上
  • DCGAN、WGAN、WGAN-GP、LSGAN、BEGAN原理总结及对比

    GAN系列学习 2 前生今世 本文已投稿至微信公众号 机器学习算法工程师 欢迎关注 本文是GAN系列学习 前世今生第二篇 在第一篇中主要介绍了GAN的原理部分 在此篇文章中 主要总结了常用的GAN包括DCGAN WGAN WGAN GP L
  • 记一次Vulnstack靶场内网渗透(五)

    实验环境搭建 VMware新建网卡VMnet14 选择仅主机模式 并将网段IP设置为192 168 138 0 然后将Windows 7和Windows 2008绑在这个VMnet14上 除此之外 还需要给Windows 7 新增一个网卡
  • C#实现俄罗斯方块游戏

    还记得小时候经常拿袖珍电子游戏机或者小霸王玩过最多的就是俄罗斯方块 冒险岛 超级玛丽还有魂斗罗之类的 这些游戏由于其中简单易上上手的特点 曾经风靡了全世界 俄罗斯方块的基本规则是移动 旋转和摆放游戏自动输出的各种方块 使之排列成完整的一行或
  • Linux开机&关机

    走进Linux系统 开机登录 开机会启动许多程序 它们在Windows叫做 服务 service 在Linux就叫做 守护进程 daemon 开机成功后 它会显示一个文本登录界面 这个界面就是我们经常看到的登录界面 在这个登录界面会提示用户
  • 关于String内存分配的深入探讨

    2019独角兽企业重金招聘Python工程师标准 gt gt gt public class Test public static final String MESSAGE taobao public static void main St
  • Sqli-labs之Less-34

    Less 34 基于错误 POST 单引号 字符型 addslashes 宽字节注入 这一关是POST型的注入 同样的将post传递过来的内容进行了转义处理 过滤了单引号 反斜杠 有之前的例子我们可以看到 df可以将转义的反斜杠给吃掉 而G
  • 数据结构 十进制和十六进制进制间的相互转换

    一 十进制转十六进制 例题 输入十进制数 654321 输出十六进制数 9FBF1 解题步骤 十进制数对16取余 因为最终结果是从下往上依次书写 说以我们可以利用栈的特性 先进 的后出 将余数存入栈中依次弹出 再将弹出的数进行拼接输出即可
  • C++迭代器-------array的基本用法总结

    基本用法中主要总结有 遍历和比较大小 注意 加上头文件 include
  • 利用python来制作动态二维码

    前言 为什么要学习python 是因为不仅很多工作需要用到python 同时我们可以利用python做很多好玩儿的事儿 今天就来教大家如何利用python制作动态二维码 代码说明 我们以小猪佩奇gif图片为例 如果我们利用的背景图是gif动
  • 工厂实施MES系统可以带来哪些效益?

    众多工厂生产现状 1 设施设备先进 但是管理方式落后 手工管理模式的存在 造成数据的不准确和不完全 没有完全实现信息化管理 2 生产计划协调性差 作业调度困难 生产作业计划主要依据调度员的经验制定 设备利用率低 任务进度监控难 紧急插单普遍
  • C++虚基类

    问题引出 问题 A中数据 在D中保存了两份 虚继承 虚继承的目的是让某个类做出声明 承诺愿意共享它的基类 其中 这个被共享的基类就称为虚基类 Virtual Base Class 虚派生只影响从指定了虚基类的派生类中进一步派生出来的类 它不
  • 扎心!为何HR看了你的简历却不通知面试?

    还只是老老实实地写简历 投简历 默默地等待面试通知 那只有两种可能 你太天真 或者是 你真的很久没有 求职 了 如果你细心观察会发现 当你完成一份简历之后 它的状态也会有变化 然而 却有很多求职者并没有搞清楚这些 状态 到底代表着什么 但小
  • idea 配置 JavaWeb 项目的 tomcat

    目录 第一步 单击 idea 靠右上部位的 添加配置 Add Config Run Config 第二步 点击 添加新 或者图中箭头指向的任意一个地方 第三步 选择 Tomcat 服务器 本地 不是 TomEE 第四步 若以前从未配置 To
  • 使用SARIMA做季节时间序列预测全流程(附MATLAB代码)

    在之前的专栏中我们用ARIMA的方法做了时间序列的趋势性预测 不过我们经常还会遇到一种情况 即某些时间序列中存在明显的周期性变化 这种周期是由于季节性变化 季度 月度等 引起的 如下图所示 为1949年到1960年每月国际航空公司的乘客人数