0


数学建模:ARMA时间序列预测

🔆 文章首发于我的个人博客:欢迎大佬们来逛逛

ARMA预测

时间序列是按时间顺序的一组数字序列
时间序列的特点:

  • 现实的、真实的一组数据,时间序列背后是某一现象的变化规律,时间序列预测就是学习之前的规律来预测后面的值

算法流程

  1. 判断时间序列数据是否平稳,若非平稳需要做差分处理
  2. 判断适合时间序列的模型,以及进行模型定阶
  3. 参数估计,产生模型
  4. 利用模型进行预测,评估预测结果
  5. 可选:绘制预测图像

代码实现(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 ==1disp("时间序列数据平稳.");elsedisp("时间序列数据不平稳,正在进行差分处理!");
        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/10if 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;endend%AIC越小越好% 绘制阶数热力图figure(3)fori=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 ==1disp("时间序列数据平稳.");elsedisp("时间序列数据不平稳,正在进行差分处理!");
        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/10if 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;endend%AIC越小越好% 绘制阶数热力图figure(3)fori=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
版权归原作者 HugeYLH 所有, 如有侵权,请联系我们删除。

“数学建模:ARMA时间序列预测”的评论:

还没有评论