• 用Python语言进行多元时间序列ARIMAX模型分析


    1.ARIMAX模型定义

      ARIMAX模型是指带回归项的ARIMA模型,又称扩展的ARIMA模型。回归项的引入有利于提高模型的预测效果。引入的回归项一般是与预测对象(即被解释变量)相关程度较高的变量。比如分析居民的消费支出序列时,消费会受到收入的影响,如果将收入也纳入到研究范围,就能够得到更精确的消费预测。

    2.ARIMAX的建模步骤

      读取数据(观察值序列)-->通过观察响应变量的时序图来判断是否需要进行差分来提取序列相关信息-->进行差分使得差分后的序列无趋势无周期-->切分训练数据与测试数据

    -->平稳性检验(一般会进行单位根检验和自相关图与偏自相关图检验)-->纯随机性检验-->协整检验(EG两步法)-->建立ARIMAX模型-->模型检验和优化-->未来预测-->做图像可视化观察

    注:本案例未进行纯随机性检验和协整检验,有需要可自行添加

    3.本案例数据查看

     案例数据中,第一列为时间序列数据,第二列为响应数据,第三列以及后每列数据为输入数据

    4.当缕清数据性质后进行操作,具体Python代码步骤如下(有省略步骤请按具体建模步骤自行添加)

      4.1倒库

    复制代码
    import pandas as pd
    import matplotlib.pyplot as plt
    import numpy as np
    from statsmodels.tsa.stattools import adfuller as ADF
    from statsmodels.graphics.tsaplots import plot_acf
    from statsmodels.graphics.tsaplots import plot_pacf
    import pyflux as pf  #pyflux库是一个专门用来建立时间序列模型的python库,需要numpy 1.23.0版本
    from sklearn.metrics import mean_absolute_error,mean_squared_error   #绝对值误差
    
    plt.rcParams['font.sans-serif'] = ['SimHei']
    plt.rcParams['axes.unicode_minus'] = False
    复制代码

      4.2读取数据

    df=pd.read_excel("时间序列的多元回归分析.xlsx")
    data=df.copy()
    data.set_index('year',inplace=True)
    #展示部分所用数据
    print(data.head())

      4.3进行一阶差分

    data=data.diff(1).iloc[1:,]
    print(data.head())

      

      4.4观察每一个标量指标经过差分后的时序图

    复制代码
    plt.figure(figsize=(20,20))
    plt.subplot(3,3,1)
    data.EXP.plot(c='r')
    plt.grid()
    plt.xlabel("年份")
    plt.ylabel("EXP")
    
    plt.subplot(3,3,2)
    data.CUR.plot(c='r')
    plt.grid()
    plt.xlabel("年份")
    plt.ylabel("CUR")
    
    plt.subplot(3,3,3)
    data.CRR.plot(c='r')
    plt.grid()
    plt.xlabel("年份")
    plt.ylabel("CRR")
    
    plt.subplot(3,3,4)
    data.D.plot(c='r')
    plt.grid()
    plt.xlabel("年份")
    plt.ylabel("D")
    
    plt.subplot(3,3,5)
    data.Trade.plot(c='r')
    plt.grid()
    plt.xlabel("年份")
    plt.ylabel("Trade")
    
    plt.subplot(3,3,6)
    data.Invest.plot(c='r')
    plt.grid()
    plt.xlabel("年份")
    plt.ylabel("Invest")
    
    plt.subplot(3,3,7)
    data.Rate.plot(c='r')
    plt.grid()
    plt.xlabel("年份")
    plt.ylabel("Rate")
    
    plt.subplot(3,3,8)
    data.Gov.plot(c='r')
    plt.grid()
    plt.xlabel("年份")
    plt.ylabel("Gov")
    
    plt.subplot(3,3,9)
    data.Pro.plot(c='r')
    plt.grid()
    plt.xlabel("年份")
    plt.ylabel("Pro")
    
    plt.show()
    复制代码

      4.5切分数据

    复制代码
    #切分数据 85%训练 15%测试
    trainnum = np.int64(data.shape[0] * 0.85)
    traindata = data.iloc[0:trainnum, :]
    testdata = data.iloc[trainnum:data.shape[0], :]
    print(traindata.shape)
    print(testdata.shape)
    复制代码

      4.6单位根检验

    复制代码
    #单位根检验:检验序列平稳性
    def Adf_test(data):
        Adftest = ADF(data, autolag='BIC')
        Adfoutput = pd.Series(Adftest[0:4], index=['Test Statistic', 'p-value', 'Lags Used', 'Number of Observations Used'])
        print(">>>{}的单位根检验结果:".format(data.name))
        print(Adfoutput)
    
    Adf_test(traindata.EXP)  # p-value  0.994235 不平稳
    Adf_test(traindata.CUR)  # p-value  0.384367 不平稳
    Adf_test(traindata.CRR)  # p-value  0.992719 不平稳
    Adf_test(traindata.D)  # p-value  1.000000 不平稳
    Adf_test(traindata.Trade)  # p-value  0.126649 不平稳
    Adf_test(traindata.Invest)  # p-value  0.236028 不平稳
    Adf_test(traindata.Rate)  # p-value  1.151937e-26 平稳
    Adf_test(traindata.Gov)  # p-value  0.999009 不平稳
    Adf_test(traindata.Pro)  # p-value  0.907343 不平稳
    复制代码

      4.7对每个差分后的数组进行自相关图与偏自相关图绘制

    复制代码
    #对每个数组进行自相关图与偏自相关图绘制
    #ACF(自相关图)、PACF(偏自相关图)
    def Acf_Pacf(data):
        f = plt.figure(facecolor='white',figsize=(6,2))
        ax1 = f.add_subplot(121)
        plot_acf(data, lags=data.shape[0]//2-1, ax=ax1)
        ax2 = f.add_subplot(122)
        plot_pacf(data, lags=data.shape[0]//2-1, ax=ax2)
        plt.show()
    
    Acf_Pacf(traindata.EXP)
    Acf_Pacf(traindata.CUR)
    Acf_Pacf(traindata.CRR)
    Acf_Pacf(traindata.D)
    Acf_Pacf(traindata.Trade)
    Acf_Pacf(traindata.Invest)
    Acf_Pacf(traindata.Rate)
    Acf_Pacf(traindata.Gov)
    Acf_Pacf(traindata.Pro)
    复制代码

      4.8建立ARIMAX模型

    #建立ARIMAX模型(利用差分后的数据进行建模,实际上仍然相当于arimax(p,d,q))
    model=pf.ARIMAX(data=traindata,formula="EXP~CUR+CRR+D+Trade+Invest+Rate+Gov+Pro",ar=1,integ=0,ma=1)
    result=model.fit("MLE")
    print(result.summary())

      4.9模型结果拟合

    #模型结果拟合
    model.plot_fit(figsize=(5,3))

      4.10未来预测数据

    复制代码
    #未来预测数据
    future=model.predict(h=testdata.shape[0],  #未来期数
                       oos_data=testdata,  #测试集数据
                       intervals=True)  #预测置信区间
    print(future)
    # print(future.to_excel("未来数据及置信区间.xlsx"))
    
    
    #未来预测图像(要注意是否进行了差分)
    model.plot_predict(h=testdata.shape[0],  #未来期数
                       oos_data=testdata,  #测试集数据
                       past_values=traindata.shape[0],
                       figsize=(6,4))
    复制代码

      4.11可视化原始数据和预测数据进行对比

    复制代码
    #可视化原始数据和预测数据进行对比
    traindata.EXP.plot(figsize=(14,7),label="训练集数据")
    testdata.EXP.plot(figsize=(14,7),label="测试集数据")
    future.EXP.plot(style="g--o",label="未来预测数据")
    #可视化出置信区间
    plt.fill_between(future.index,future["5% Prediction Interval"],
                     future["95% Prediction Interval"],color='blue',alpha=0.15,
                     label="95%置信区间")
    plt.grid()
    plt.xlabel("Time")
    plt.ylabel("EXP")
    plt.title("ARIMAX(1,0,1)模型")
    # plt.legend(loc=0)
    plt.show()
    复制代码

      4.12模型优化,通过遍历寻找合适的 p,q

    复制代码
    #通过遍历寻找合适的 p,q
    p = np.arange(6)
    q = np.arange(6)
    pp,qq = np.meshgrid(p,q)
    resultdf = pd.DataFrame(data = {"arp":pp.flatten(),"mrq":qq.flatten()})
    resultdf["bic"] = np.double(pp.flatten())
    resultdf["mae"] = np.double(qq.flatten())
    ## 迭代循环建立多个模型
    for ii in resultdf.index:
        model_i = pf.ARIMAX(data=traindata,formula="EXP~CUR+CRR+D+Trade+Invest+Rate+Gov+Pro",ar=resultdf.arp[ii],ma=resultdf.mrq[ii],integ=0)
        try:
            modeli_fit = model_i.fit("MLE")
            bic = modeli_fit.bic
            EXP_pre = model.predict(h=testdata.shape[0],oos_data=testdata)
            mae = mean_absolute_error(testdata.EXP,EXP_pre.EXP)
        except:
            bic = np.nan
        resultdf.bic[ii] = bic
        resultdf.mae[ii] = mae   #绝对值误差
    print("模型迭代结束")
    print(resultdf.sort_values(by="bic").head())
    #此时找到了最优的arma参数,换掉之前的模型参数即可
    复制代码

     

      到此,多元时间序列建模基本结束!

  • 相关阅读:
    Vue 登录密码验证 MD5加密
    程序员的护城河有哪些
    5 款轻松上手的开源项目「GitHub 热点速览」
    【CSS布局】—— flex(弹性)布局
    web前端期末大作业:基于HTML+CSS+JavaScript实现网上鲜花店网站设计(14页)
    Python ... takes 0 positional arguments but 1 was given
    基于Hi3861的听话的狗子
    我与梅西粉丝们的世界杯观球日常
    介绍Spring MVC框架,以及如何使用它构建Web应用程序。
    「图论」判环、求环、最小环
  • 原文地址:https://www.cnblogs.com/hongbao/p/17625963.html