数学建模:ARMA时间序列预测
短信预约 -IT技能 免费直播动态提醒
🔆 文章首发于我的个人博客:欢迎大佬们来逛逛
ARMA预测
时间序列是按时间顺序的一组数字序列
时间序列的特点:
- 现实的、真实的一组数据,时间序列背后是某一现象的变化规律,时间序列预测就是学习之前的规律来预测后面的值
算法流程
- 判断时间序列数据是否平稳,若非平稳需要做差分处理
- 判断适合时间序列的模型,以及进行模型定阶
- 参数估计,产生模型
- 利用模型进行预测,评估预测结果
- 可选:绘制预测图像
代码实现(1)
预测指定的 L
个数据。
function [ret_predict] = mfunc_ARMA_L(trainData,L) % ARMA预测 % params: % trainData: 训练原始数据 Shape: (1,n) % L: 预测数据个数 % returns: % predict: 预测的值 Shape:(1,L) % 判断时间序列数据是否平稳 1代表平稳,0代表不平稳 is_stable = adftest(trainData); if is_stable == 1 disp("时间序列数据平稳."); else disp("时间序列数据不平稳,正在进行差分处理!"); diff_trainData = diff(trainData); % 进行差分处理 disp("差分处理完成!"); end % 利用自相关图和偏相关图判断模型类型和阶次 figure(1) autocorr(diff_trainData) %绘制自相关函数 -> MA [ACF,Lags,Bounds]=autocorr(trainData); figure(2) parcorr(diff_trainData) %绘制偏相关函数 -> AR % 自相关和偏相关函数难以判断时可以用AIC准则求出最好阶数 %确定阶数的上限 lim=round(length(trainData)/10); %数据总长度的1/10 if lim>=10 lim=10;%如果数据太长了,就限定阶数 end id_trainData=iddata(trainData'); % saveData=[]; for p=1:lim for q=1:lim num=armax(id_trainData,[p,q]); %armax对应FPE最小 AIC=aic(num); %AIC可以衡量阶数好不好 saveData=[saveData;p q AIC]; hotMatrix(p,q)=AIC; end end %AIC越小越好 % 绘制阶数热力图 figure(3) for i=1:lim y_index(1,i)={['AR' ,num2str(i)]}; x_index(1,i)={['MA' ,num2str(i)]}; end H = heatmap(x_index,y_index, hotMatrix, 'FontSize',12, 'FontName','宋体'); H.Title = 'AIC定阶热力图'; %AIC越小越好 % 利用阶数得到模型 min_index=find(saveData(:,3)==min(saveData(:,3))); p_best=saveData(min_index,1); %p的最优阶数 q_best=saveData(min_index,2); %q的最优阶数 model = armax(id_trainData,[p_best,q_best]); % 利用模型预测,对划分的测试集测试 % L=length(testData); 参数中给出 pre_data=[diff_trainData';zeros(L,1)]; pre_data1=iddata(pre_data); % 做成时间序列预测 pre_data2=predict(model,pre_data1,L); pre_data3=get(pre_data2);%得到结构体 pre_data4=pre_data3.OutputData{1,1}(length(diff_trainData)+1:length(diff_trainData)+L);%从结构体里面得到数据 %显示全部 data1=[diff_trainData';pre_data4];%全部的差分值 if is_stable==0 %非平稳时进行差分还原 data_pre1=cumsum([trainData(1);data1]);%还原差分值 else data_pre1=data1; end % 最终预测 data_pre2=data_pre1(length(trainData)+1:end);%最终预测值 figure(4) plot(1:length(trainData),trainData,'--','LineWidth',1) hold on plot(length(trainData)+1:length(trainData)+L,data_pre2,'--','LineWidth',1.5) hold on xlabel('time') ylabel('price') legend('真实值','预测值') ret_predict = data_pre2; % 返回值end
代码实现(2)
输入一个 test测试真实值,检查预测值与真实值的相似度。
function [ret_predict] = mfunc_ARMA(trainData,testData) % ARMA预测 % params: % trainData: 训练原始数据 Shape: (1,n) % testData: 测试比较数据 Shape(1,L) % returns: % predict: 预测的值 Shape:(1,L) % 判断时间序列数据是否平稳 1代表平稳,0代表不平稳 is_stable = adftest(trainData); if is_stable == 1 disp("时间序列数据平稳."); else disp("时间序列数据不平稳,正在进行差分处理!"); diff_trainData = diff(trainData); % 进行差分处理 disp("差分处理完成!"); end % 利用自相关图和偏相关图判断模型类型和阶次 figure(1) autocorr(diff_trainData) %绘制自相关函数 -> MA [ACF,Lags,Bounds]=autocorr(trainData); figure(2) parcorr(diff_trainData) %绘制偏相关函数 -> AR % 自相关和偏相关函数难以判断时可以用AIC准则求出最好阶数 %确定阶数的上限 lim=round(length(trainData)/10); %数据总长度的1/10 if lim>=10 lim=10;%如果数据太长了,就限定阶数 end id_trainData=iddata(trainData'); % saveData=[]; for p=1:lim for q=1:lim num=armax(id_trainData,[p,q]); %armax对应FPE最小 AIC=aic(num); %AIC可以衡量阶数好不好 saveData=[saveData;p q AIC]; hotMatrix(p,q)=AIC; end end %AIC越小越好 % 绘制阶数热力图 figure(3) for i=1:lim y_index(1,i)={['AR' ,num2str(i)]}; x_index(1,i)={['MA' ,num2str(i)]}; end H = heatmap(x_index,y_index, hotMatrix, 'FontSize',12, 'FontName','宋体'); H.Title = 'AIC定阶热力图'; %AIC越小越好 % 利用阶数得到模型 min_index=find(saveData(:,3)==min(saveData(:,3))); p_best=saveData(min_index,1); %p的最优阶数 q_best=saveData(min_index,2); %q的最优阶数 model = armax(id_trainData,[p_best,q_best]); % 利用模型预测,对划分的测试集测试 L=length(testData); pre_data=[diff_trainData';zeros(L,1)]; pre_data1=iddata(pre_data); % 做成时间序列预测 pre_data2=predict(model,pre_data1,L); pre_data3=get(pre_data2);%得到结构体 pre_data4=pre_data3.OutputData{1,1}(length(diff_trainData)+1:length(diff_trainData)+L);%从结构体里面得到数据 %显示全部 data1=[diff_trainData';pre_data4];%全部的差分值 if is_stable==0 %非平稳时进行差分还原 data_pre1=cumsum([trainData(1);data1]);%还原差分值 else data_pre1=data1; end % 最终预测 data_pre2=data_pre1(length(trainData)+1:end);%最终预测值 figure(4) subplot(2,1,1) plot(1:length(trainData),trainData,'--','LineWidth',1) hold on plot(length(trainData)+1:length(trainData)+L,testData,'--','LineWidth',1.5) hold on plot(length(trainData)+1:length(trainData)+L,data_pre2,'--','LineWidth',1.5) hold on xlabel('time') ylabel('price') legend('真实值','测试数据真实值','预测值') ret_predict = data_pre2; % 返回值 wucha=sum(abs(data_pre2'-testData)./testData)./length(data_pre2); title_str=['ARMA法',' 预测相对误差为:',num2str(wucha)]; title(title_str) subplot(2,1,2) plot(1:L,testData,'--o','LineWidth',1.5) hold on plot(1:L,data_pre2,'--*','LineWidth',1.5) hold on xlabel('time') ylabel('price') legend('真实值','预测值') title_str=['ARMA法',' 预测相对误差为:',num2str(wucha)]; title(title_str)end
来源地址:https://blog.csdn.net/jj6666djdbbd/article/details/132553788
免责声明:
① 本站未注明“稿件来源”的信息均来自网络整理。其文字、图片和音视频稿件的所属权归原作者所有。本站收集整理出于非商业性的教育和科研之目的,并不意味着本站赞同其观点或证实其内容的真实性。仅作为临时的测试数据,供内部测试之用。本站并未授权任何人以任何方式主动获取本站任何信息。
② 本站未注明“稿件来源”的临时测试数据将在测试完成后最终做删除处理。有问题或投稿请发送至: 邮箱/279061341@qq.com QQ/279061341