gpt4 book ai didi

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

转载 作者:我是一只小鸟 更新时间:2023-08-13 06:31:06 24 4
gpt4 key购买 nike

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参数,换掉之前的模型参数即可
                          
                        

  。

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

最后此篇关于用Python语言进行多元时间序列ARIMAX模型分析的文章就讲到这里了,如果你想了解更多关于用Python语言进行多元时间序列ARIMAX模型分析的内容请搜索CFSDN的文章或继续浏览相关文章,希望大家以后支持我的博客! 。

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com