用Python语言进行时间序列ARIMA模型分析

科技资讯 投稿 7300 0 评论

用Python语言进行时间序列ARIMA模型分析

应用时间序列

1.经济预测:时间序列分析可以用来分析经济数据,预测未来经济趋势和走向。例如,利用历史股市数据和经济指标进行时间序列分析,可以预测未来股市的走向。

3.天气预测:时间序列分析可以用于天气预测,例如预测未来几天或几周的降雨量、温度等。这对于农业生产和水资源的管理非常重要。

5.工业控制:时间序列分析可以用来优化工业生产过程。例如,根据机器运行状态和历史生产数据,可以建立一个时间序列模型来优化生产线的运行,提高生产效率。

源数据样例:

以下是数据的具体时间序列分析步骤:

注意:以下时间序列分析代码仅限一阶差分或者不使用差分进行的代码,以一阶差分为例。

一.导入数据

1 df=pd.read_excel('M17.xlsx' 2 print(df["水位"].head( 3 4 # 创建一个DatetimeIndex对象,指定时间范围为2021年1月1日到1月5日 5 dates = pd.date_range(start='1860-01-01', end='1955-12-31',freq='AS' 6 # 创建一个Series对象,将列表作为数据,DatetimeIndex对象作为索引 7 t_s = pd.Series(data=df["水位"].tolist(, index=dates 8 t_s.index = t_s.index.strftime('%Y'

注:这里的数据df为dataframe数据,两列;t_s为时间序列数据,第二列,它内涵时间索引

二.绘制时序图

一个典型的时序图通常包括以下几个元素:

2-->Y轴:表示变量的取值范围,通常根据数据的特性来设置刻度。例如,如果数据表示某个产品的销售额,则Y轴可能显示金额数值;如果数据表示温度,则Y轴可能显示摄氏度或华氏度。、

4-->标题和注释:用于说明时序图的含义、数据来源和相关信息。

首先可以绘制线图直接观察数据走势粗略判断平稳性,既无趋势也无周期

1 #时序图 2 plt.plot(df['年份'],df['水位'] 3 plt.xlabel("年份" 4 plt.ylabel("水位" 5 plt.show(

三.初步检验

3.1.纯随机性检验(白噪声检验)

3.1.1Ljung-Box 检验

Ljung-Box 检验是基于自相关和偏自相关函数计算的。在实际应用中,需要将时间序列数据转化为平稳序列,然后计算其自相关和偏自相关函数。Ljung-Box 检验会统计一组拉格朗日乘子(Lagrange Multiplier)值,从而判断序列数据是否具有白噪声特征。

print("随机性检验:",'\n',lb_test(df["水位"], return_df=True,lags=5

lags 参数指定计算自相关和偏自相关函数的滞后阶数。如果希望以一定的置信度进行 Ljung-Box 检验,可以根据自由度和置信度水平计算出对应的临界值,然后将其与 stat 进行比较。

注:当p值小于0.05时为显著非白噪声序列

3.1.2单位根检验:ADF检验

单位根检验旨在验证时间序列数据是否具有平稳性。如果时间序列数据具有单位根,则说明数据存在非平稳性,并且预测和分析可能会出现问题。因此,在进行时间序列分析之前,我们需要先进行单位根检验,以确保数据具有平稳性。

除了ADF检验外,还有许多其他的单位根检验方法,例如Dickey-Fuller检验、KPSS检验等。不同的单位根检验方法具有不同的假设条件和适用范围,需要根据具体情况来选择合适的方法。

检验假设:H0:存在单位根 vs H1:不存在单位根

如果序列平稳,则不应存在单位根,所以我们希望能拒绝原假设

1 # 进行ADF检验 2 result = ts.adfuller(df['水位'] 3 # 输出ADF结果 4 print('-------------------------------------------' 5 print('ADF检验结果:' 6 print('ADF Statistic: %f' % result[0] 7 print('p-value: %f' % result[1] 8 print('Lags Used: %d' % result[2] 9 print('Observations Used: %d' % result[3] 10 print('Critical Values:' 11 for key, value in result[4].items(: 12 print('\t%s: %.3f' % (key, value

当p-value>0.05,则要进行差分运算!否之直接跳转到模型选择与定阶。

 3.2差分运算

差分运算可以通过计算序列中相邻数据之间的差值得到。一阶差分是指将每个数值与其前一个数值相减,得到一个新的序列;二阶差分是指对一阶差分后的序列再进行一次差分运算,以此类推。

1 ##### 差分运算 2 def diff(timeseries: 3 new_df=timeseries.diff(periods=1.dropna(#dropna删除NaN 4 new_df.plot(color='orange',title='diff1' 5 return new_df 6 7 #进行一阶差分 8 ndf=diff(df['水位']

或者如下方式也可以进行差分

ndf = pd.Series(np.diff(df['水位'], n=1

注:n=1表示1阶差分

3.3再次进行ADF检验

1 #再次进行ADF检验 2 result2 = ts.adfuller(ndf 3 # 输出ADF结果 4 print('-------------------------------------------' 5 print('差分后序列的ADF检验结果:' 6 print('ADF Statistic: %f' % result2[0] 7 print('p-value: %f' % result2[1] 8 print('Lags Used: %d' % result2[2] 9 print('Observations Used: %d' % result2[3] 10 print('Critical Values:' 11 for key, value in result2[4].items(: 12 print('\t%s: %.3f' % (key, value

如果p-value<0.05则进行下一步定阶;如p-value仍然>0.05,则继续进行差分,再进行ADF检验,直到检验结果的p-value<0.05则进行下一步定阶。

四.模型选择与定阶

4.1自相关图和偏自相关图人工定阶

自相关图和偏自相关图是时序数据分析中常用的工具,可以帮助我们理解时间序列数据中的自相关性和互相关性。自相关函数(ACF)和偏自相关函数(PACF)是计算自相关图和偏自相关图的数学概念。

自相关图展示了时间序列数据在不同滞后阶数下的自相关系数,即前一时间点与后面所有时间点之间的相关性。自相关图有助于判断时间序列数据是否存在季节性或周期性变化,并且可以用来选择合适的时间序列模型。如果一个时间序列数据存在季节性变化,则其自相关图通常会呈现出明显的周期性模式。

偏自相关图展示了在滞后阶数为 n 时,在其他阶数的影响已被削减的情况下,上一时间点与当前时间点之间的相关性。偏自相关图可以帮助我们确定时间序列数据中的短期相关性,从而选择合适的时间序列模型。如果一个时间序列数据存在短期相关性,则其偏自相关图通常会显示出急速衰减的模式。

模型定阶就是根据自相关图和偏自相关图来确定时间序列模型的阶数。一般建议先使用自相关图和偏自相关图来判断时间序列数据的性质和模型类型,然后根据其结果选择适当的时间序列模型及其阶数。常用的时间序列模型包括 AR、MA、ARMA 和 ARIMA 等。

1 #模型选择:绘制ACF与PACF,即自相关图和偏自相关图 2 #### 绘制ACF与PACF的图像 3 def plot_acf_pacf(timeseries: #利用ACF和PACF判断模型阶数 4 plot_acf(timeseries,lags=timeseries.shape[0]%2 #延迟数 5 plot_pacf(timeseries,lags=timeseries.shape[0]%2 6 plt.show( 7 plot_acf_pacf(ndf

4.2利用AIC与BIC准则进行迭代调优

一般来说,AIC 和 BIC 的值越小,表示模型对数据的解释能力越强,预测结果也更加可信。

利用 AIC 和 BIC 进行迭代调优的基本思路如下:

2-->对模型进行迭代调优。例如,可以逐步增加 AR 或 MA 的阶数,或者使用其他方法来改进模型的性能。每次更新模型后,重新计算 AIC 和 BIC 值,并与之前的值进行比较。

需要注意的是,AIC 和 BIC 只是一种近似的模型评价指标。在实际应用中,还需要考虑其他因素,例如模型的可解释性、预测误差等。因此,在选择时间序列模型时,需要综合考虑多个因素,以选择最合适的模型。

1 #迭代调优 2 print('-------------------------------------------' 3 #AIC 4 timeseries=ndf 5 AIC=sm.tsa.stattools.arma_order_select_ic(timeseries,max_ar=4,max_ma=4,ic='aic'['aic_min_order'] 6 #BIC 7 BIC=sm.tsa.stattools.arma_order_select_ic(timeseries,max_ar=4,max_ma=4,ic='bic'['bic_min_order'] 8 print('the AIC is{}\nthe BIC is{}\n'.format(AIC,BIC

五.模型构建

ARIMA 模型是一种常用的时间序列分析模型,可以用来预测未来一段时间内的数据趋势。ARIMA 的全称是 Autoregressive Integrated Moving Average,其中 Autoregressive 表示自回归模型,Integrated 表示差分操作,Moving Average 表示滑动平均模型。

·AR 模型是指基于前期观测值的线性组合,来预测当前观测值的模型。AR 模型的阶数 p 表示使用前 p 个时刻的观测值来预测当前时刻的值。

·MA 模型是指基于前期观测值的随机误差的线性组合,来预测当前观测值的模型。MA 模型的阶数 q 表示使用前 q 个时刻的随机误差来预测当前时刻的值。

1 #模型构建 2 print('-------------------------------------------' 3 model= ARIMA(ndf, order=(1, 1, 2.fit( 4 print(model.params 5 print(model.summary(

六.模型后检验

6.1残差检验

通常情况下,如果残差服从正态分布、均值为零、方差相等,则说明模型拟合良好。而如果残差不满足上述条件,则表明模型可能存在问题,需要进一步调整或改进。

1-->绘制残差图:将样本数据的残差绘制成散点图,观察其是否随着自变量的增加而呈现出某种规律,比如呈现出线性或非线性关系。如果残差呈现出某种规律,则表明模型存在问题。

3-->进行统计检验:利用统计学方法检验残差是否服从正态分布。常用的检验方法包括Kolmogorov-Smirnov检验、Shapiro-Wilk检验等。

残差图:

1 #残差图 2 model.resid.plot(figsize=(10,3 3 plt.show(

6.2Jarque-Bera检验

在Jarque-Bera检验中,我们首先计算样本数据的偏度和峰度,然后根据公式计算出JB统计量,最后对其进行显著性检验。

Jarque-Bera检验的原假设是:样本数据符合正态分布。如果p值较小,则拒绝原假设,即认为样本数据不符合正态分布。

1 #进行Jarque-Bera检验 2 print('-------------------------------------------' 3 jb_test = sm.stats.stattools.jarque_bera(model.resid 4 print('Jarque-Bera test:' 5 print('JB:', jb_test[0] 6 print('p-value:', jb_test[1] 7 print('Skew:', jb_test[2] 8 print('Kurtosis:', jb_test[3]

6.3Ljung-Box检验

在进行Ljung-Box检验时,我们首先计算时间序列模型的残差,并对其进行平方处理(Q值)。然后根据公式计算出LB统计量和相应的p值,最后对其进行显著性检验。

Ljung-Box检验的原假设是:时间序列模型的残差之间不存在自相关性。如果p值较小,则拒绝原假设,即认为残差之间存在显著的自相关性。

1 print('-------------------------------------------' 2 lb_test= sm.stats.diagnostic.acorr_ljungbox(model.resid, return_df=True,lags=5 3 print('Ljung-Box test:','\n',lb_test

6.4DW检验

DW统计量的取值范围为0~4,当DW统计量接近2时,表明误差项不存在一阶自相关;DW小于2,则存在正自相关;DW大于2则存在负自相关。根据经验规律,DW统计量在1.5 ~ 2.5之间可以认为不存在自相关;小于1.5表示存在正自相关;大于2.5表示存在负自相关。

1 # 进行DW检验 2 print('-------------------------------------------' 3 dw_test = sm.stats.stattools.durbin_watson(model.resid 4 print('Durbin-Watson test:' 5 print('DW:', dw_test

6.5利用QQ图看正态性

如果样本分布与理论分布一致,则散点图应该大致呈现出一条直线。如果两者之间存在差异,则散点图会偏离一条直线,并呈现出“S”型或其他非线性形状,这表明样本数据的分布与理论分布不一致。

1 #QQ图看正态性 2 qqplot(model.resid, line="q", fit=True 3 plt.show(

七.模型评价

7.1生成模型预测数据

代原值计算后 通过反向差分运算(前期没有进行差分运算则不需要,前期差分运算了几步这里要反向运算几步)的数据 与 原数据(真实数据)进行比对。

1 #模型预测 2 print('-------------------------------------------' 3 predict= model.predict(1,95#dynamic=True 4 # print('模型预测:','\n',predict 5 #反向差分运算 6 # 对差分后的时间序列进行逆差分运算,两个参数:差分数据序列和原始数据序列 7 def inverse_diff(diff_series, original_series: 8 inverted = [] 9 prev = original_series.iloc[0] 10 for val in diff_series: 11 current = val + prev 12 inverted.append(current 13 prev = current 14 return pd.Series(inverted, index=original_series.index[1:] 15 n_predict=inverse_diff(predict,t_s 16 print('模型预测:','\n',n_predict

7.2真实值与预测值划入同意图像进行比对

1 # #画图 2 plt.figure(figsize=(10,4 3 plt.plot(t_s.index,t_s,label='actual' 4 plt.plot(predict.index,n_predict,label='predict' 5 plt.xticks([] 6 plt.legend(['actual','predict'] 7 plt.xlabel('time(year' 8 plt.ylabel('SUNACTIVITY' 9 plt.show(

八.未来数据预测

 1 print('-------------------------------------------'
 2 # 进行三步预测,并输出95%置信区间
 3 steps=3   #未来三期预测
 4 forecast= model.get_forecast(steps=steps
 5 table=pd.DataFrame(forecast.summary_frame(
 6 
 7 # print(table.iloc[1]
 8 table.iloc[0]=table.iloc[0]+t_s[-1]
 9 # print(table.iloc[0, 0]
10 for i in range(steps-1:
11     table.iloc[i+1]=table.iloc[i+1]+table.iloc[i, 0]
12 print(table

Python完整代码:

import numpy as np import pandas as pd import matplotlib.pyplot as plt import statsmodels.api as sm from statsmodels.graphics.tsaplots import plot_acf,plot_pacf #ACF与PACF import statsmodels.tsa.stattools as ts #adf检验 from statsmodels.tsa.arima.model import ARIMA #ARIMA模型 from statsmodels.graphics.api import qqplot #qq图 from statsmodels.stats.diagnostic import acorr_ljungbox as lb_test #用于LingBox随机性检验 plt.rcParams['font.sans-serif'] = ['SimHei'] plt.rcParams['axes.unicode_minus'] = False df=pd.read_excel('M17.xlsx' print(df["水位"].head( # 创建一个DatetimeIndex对象,指定时间范围为2021年1月1日到1月5日 dates = pd.date_range(start='1860-01-01', end='1955-12-31',freq='AS' # 创建一个Series对象,将列表作为数据,DatetimeIndex对象作为索引 t_s = pd.Series(data=df["水位"].tolist(, index=dates t_s.index = t_s.index.strftime('%Y' #时序图 plt.plot(df['年份'],df['水位'] plt.xlabel("年份" plt.ylabel("水位" plt.show( #纯随机性检验(白噪声检验) #Ljung-Box 检验,LB检验,用来做纯随机性检验的,单位根检验也属于 print('-------------------------------------------' print("随机性检验:",'\n',lb_test(df["水位"], return_df=True,lags=5 # 进行ADF检验 result = ts.adfuller(df['水位'] # 输出ADF结果 print('-------------------------------------------' print('ADF检验结果:' print('ADF Statistic: %f' % result[0] print('p-value: %f' % result[1] print('Lags Used: %d' % result[2] print('Observations Used: %d' % result[3] print('Critical Values:' for key, value in result[4].items(: print('\t%s: %.3f' % (key, value ##### 差分运算 def diff(timeseries: new_df=timeseries.diff(periods=1.dropna(#dropna删除NaN new_df.plot(color='orange',title='diff1' return new_df #进行一阶差分 print("============================================================" ndf=diff(df["水位"] print(ndf # dif = pd.Series(np.diff(df['水位'], n=1 # print(dif #再次进行ADF检验 result2 = ts.adfuller(ndf # 输出ADF结果 print('-------------------------------------------' print('差分后序列的ADF检验结果:' print('ADF Statistic: %f' % result2[0] print('p-value: %f' % result2[1] print('Lags Used: %d' % result2[2] print('Observations Used: %d' % result2[3] print('Critical Values:' for key, value in result2[4].items(: print('\t%s: %.3f' % (key, value #模型选择与定阶 #模型选择:绘制ACF与PACF,即自相关图和偏自相关图 #### 绘制ACF与PACF的图像 def plot_acf_pacf(timeseries: #利用ACF和PACF判断模型阶数 plot_acf(timeseries,lags=timeseries.shape[0]%2 #延迟数 plot_pacf(timeseries,lags=timeseries.shape[0]%2 plt.show( plot_acf_pacf(ndf #迭代调优 print('-------------------------------------------' #AIC timeseries=ndf AIC=sm.tsa.stattools.arma_order_select_ic(timeseries,max_ar=4,max_ma=4,ic='aic'['aic_min_order'] #BIC BIC=sm.tsa.stattools.arma_order_select_ic(timeseries,max_ar=4,max_ma=4,ic='bic'['bic_min_order'] print('the AIC is{}\nthe BIC is{}\n'.format(AIC,BIC #模型构建 print('-------------------------------------------' model= ARIMA(ndf, order=(1, 1, 2.fit( print(model.params print(model.summary( #残差检验:检验残差是否服从正态分布,画图查看,然后检验 #残差图 model.resid.plot(figsize=(10,3 plt.show( #进行Jarque-Bera检验 print('-------------------------------------------' jb_test = sm.stats.stattools.jarque_bera(model.resid print('Jarque-Bera test:' print('JB:', jb_test[0] print('p-value:', jb_test[1] print('Skew:', jb_test[2] print('Kurtosis:', jb_test[3] # 进行Ljung-Box检验 print('-------------------------------------------' lb_test= sm.stats.diagnostic.acorr_ljungbox(model.resid, return_df=True,lags=5 print('Ljung-Box test:','\n',lb_test # 进行DW检验 print('-------------------------------------------' dw_test = sm.stats.stattools.durbin_watson(model.resid print('Durbin-Watson test:' print('DW:', dw_test #QQ图看正态性 qqplot(model.resid, line="q", fit=True plt.show( #模型预测 print('-------------------------------------------' predict= model.predict(1,95#dynamic=True # print('模型预测:','\n',predict #反向差分运算 # 对差分后的时间序列进行逆差分运算,两个参数:差分数据序列和原始数据序列 def inverse_diff(diff_series, original_series: inverted = [] prev = original_series.iloc[0] for val in diff_series: current = val + prev inverted.append(current prev = current return pd.Series(inverted, index=original_series.index[1:] n_predict=inverse_diff(predict,t_s print('模型预测:','\n',n_predict # #画图 plt.figure(figsize=(10,4 plt.plot(t_s.index,t_s,label='actual' plt.plot(predict.index,n_predict,label='predict' plt.xticks([] plt.legend(['actual','predict'] plt.xlabel('time(year' plt.ylabel('SUNACTIVITY' plt.show( print('-------------------------------------------' # 进行三步预测,并输出95%置信区间 steps=3 #未来三期预测 forecast= model.get_forecast(steps=steps table=pd.DataFrame(forecast.summary_frame( # print(table.iloc[1] table.iloc[0]=table.iloc[0]+t_s[-1] # print(table.iloc[0, 0] for i in range(steps-1: table.iloc[i+1]=table.iloc[i+1]+table.iloc[i, 0] print(table

View Code

 

Python的完整包装之后的库:

1 import numpy as np 2 import pandas as pd 3 import matplotlib.pyplot as plt 4 import statsmodels.api as sm 5 from statsmodels.graphics.tsaplots import plot_acf,plot_pacf #ACF与PACF 6 import statsmodels.tsa.stattools as ts #adf检验 7 from statsmodels.tsa.arima.model import ARIMA #ARIMA模型 8 from statsmodels.graphics.api import qqplot #qq图 9 from statsmodels.stats.diagnostic import acorr_ljungbox as lb_test #用于LingBox随机性检验 10 11 plt.rcParams['font.sans-serif'] = ['SimHei'] 12 plt.rcParams['axes.unicode_minus'] = False 13 14 class Time_ARIMA(: 15 def __init__(self,path: 16 try: 17 self.df = pd.read_csv(path 18 except: 19 self.df=pd.read_excel(path 20 # print(self.df.iloc[:,0] 21 start=str(self.df.iloc[0,0]+'-01-01' 22 end=str(self.df.iloc[-1,0]+'-01-01' 23 # 创建一个DatetimeIndex对象,指定时间范围为2021年1月1日到1月5日 24 dates = pd.date_range(start=start, end=end, freq='AS' 25 # 创建一个Series对象,将列表作为数据,DatetimeIndex对象作为索引 26 self.t_s = pd.Series(data=self.df.iloc[:,1].tolist(, index=dates 27 self.t_s.index = self.t_s.index.strftime('%Y' 28 # print(self.t_s 29 self.timeseries=None 30 self.flag=0 31 self.BIC=None 32 self.model=None 33 34 def Timing_Diagram(self: 35 # 时序图 36 plt.plot(self.t_s 37 plt.xlabel(self.df.iloc[:,0].name 38 plt.xticks(np.arange(0,self.df.shape[0], step=10 #设置横坐标间距 39 plt.ylabel(self.df.iloc[:,1].name 40 plt.show( 41 42 def Diff_pre_sequence_test(self: 43 # 纯随机性检验(白噪声检验) 44 # Ljung-Box 检验,LB检验,用来做纯随机性检验的,单位根检验也属于 45 print('==================原始序列的纯随机性检验==================' 46 print("Ljung-Box检验:", '\n', lb_test(self.df.iloc[:,1], return_df=True, lags=5 47 # 进行ADF检验 48 result = ts.adfuller(self.df.iloc[:,1] 49 # 输出ADF结果 50 print('---------------------ADF检验结果----------------------' 51 print('ADF Statistic: %f' % result[0] 52 print('p-value: %f' % result[1] 53 print('Lags Used: %d' % result[2] 54 print('Observations Used: %d' % result[3] 55 print('Critical Values:' 56 for key, value in result[4].items(: 57 print('\t%s: %.3f' % (key, value 58 print('====================================================' 59 60 def Diff_operation(self,timeseries=None: 61 try: 62 #二阶及以上差分 63 ndf = timeseries.diff(periods=1.dropna( # dropna删除NaN 64 except: 65 #一阶差分 66 ndf = self.t_s.diff(periods=1.dropna( # dropna删除NaN 67 ndf.plot(color='orange', title='残差图' 68 self.flag+=1 69 self.timeseries=ndf 70 print(self.flag 71 return ndf 72 73 def Diff_after_sequence_testing(self: 74 # 再次进行ADF检验 75 if self.flag==0: 76 print("未进行差分运算,不必再次进行ADF检验" 77 else: 78 result2 = ts.adfuller(self.timeseries 79 # 输出ADF结果 80 print('------------差分后序列的ADF检验结果------------' 81 print('ADF Statistic: %f' % result2[0] 82 print('p-value: %f' % result2[1] 83 print('Lags Used: %d' % result2[2] 84 print('Observations Used: %d' % result2[3] 85 print('Critical Values:' 86 for key, value in result2[4].items(: 87 print('\t%s: %.3f' % (key, value 88 89 90 def ACF_and_PACF(self: 91 # 绘制ACF与PACF的图像,利用ACF和PACF判断模型阶数 92 # print(int(self.t_s.shape[0]/2 93 if self.flag == 0: 94 plot_acf(self.t_s, lags=int(self.t_s.shape[0] / 2 - 1 # 延迟数 95 plot_pacf(self.t_s, lags=int(self.t_s.shape[0] / 2 - 1 96 plt.show( 97 else: 98 plot_acf(self.timeseries, lags=int(pd.Series(self.timeseries.shape[0] / 2 - 1 # 延迟数 99 plot_pacf(self.timeseries, lags=int(pd.Series(self.timeseries.shape[0] / 2 - 1 100 plt.show( 101 102 def Model_order_determination(self: 103 # 迭代调优 104 if self.flag==0: 105 timeseries=self.t_s 106 else: 107 timeseries=self.timeseries 108 # AIC 109 AIC = sm.tsa.stattools.arma_order_select_ic(timeseries, max_ar=4, max_ma=4, ic='aic'['aic_min_order'] 110 # BIC 111 BIC = sm.tsa.stattools.arma_order_select_ic(timeseries, max_ar=4, max_ma=4, ic='bic'['bic_min_order'] 112 print('---AIC与BIC准则定阶---' 113 print('the AIC is{}\nthe BIC is{}\n'.format(AIC, BIC,end='' 114 print('--------------------' 115 self.BIC=BIC 116 117 def Model_building(self: 118 if self.flag==0: 119 timeseries=self.t_s 120 else: 121 timeseries=self.timeseries 122 model = ARIMA(timeseries, order=(self.BIC[0], self.flag, self.BIC[1].fit( 123 print('--------参数估计值-------' 124 print(model.params 125 print(model.summary( 126 self.model=model 127 128 def Model_building_artificial(self,order=(0,0,0: 129 if self.flag==0: 130 timeseries=self.t_s 131 else: 132 timeseries=self.timeseries 133 model = ARIMA(timeseries, order=order.fit( 134 print('--------参数估计值-------' 135 print(model.params 136 print(model.summary( 137 self.model = model 138 139 def Model_checking(self: 140 # 残差检验:检验残差是否服从正态分布,画图查看,然后检验 141 # 残差图 142 self.model.resid.plot(figsize=(10, 3 143 plt.title("残差图" 144 plt.show( 145 146 # 进行Jarque-Bera检验 147 jb_test = sm.stats.stattools.jarque_bera(self.model.resid 148 print("==================================================" 149 print('------------Jarque-Bera检验-----------' 150 print('Jarque-Bera test:' 151 print('JB:', jb_test[0] 152 print('p-value:', jb_test[1] 153 print('Skew:', jb_test[2] 154 print('Kurtosis:', jb_test[3] 155 156 # 进行Ljung-Box检验 157 lb_test = sm.stats.diagnostic.acorr_ljungbox(self.model.resid, return_df=True, lags=5 158 print('------------Ljung-Box检验-------------' 159 print('Ljung-Box test:', '\n', lb_test 160 161 # 进行DW检验 162 dw_test = sm.stats.stattools.durbin_watson(self.model.resid 163 print('---------------DW检验----------------' 164 print('Durbin-Watson test:' 165 print('DW:', dw_test 166 print("==================================================" 167 168 # QQ图看正态性 169 qqplot(self.model.resid, line="q", fit=True 170 plt.title("Q-Q图" 171 plt.show( 172 173 def Model_prediction_accuracy(self: 174 # 模型预测 175 if self.flag==0: 176 n_predict = self.model.predict(1, self.t_s.shape[0] 177 print('模型预测:', '\n', n_predict 178 else: 179 # 反向差分运算 180 # 对差分后的时间序列进行逆差分运算,两个参数:差分数据序列和原始数据序列 181 def inverse_diff(diff_series, original_series: 182 inverted = [] 183 prev = original_series.iloc[0] 184 for val in diff_series: 185 current = val + prev 186 inverted.append(current 187 prev = current 188 return pd.Series(inverted, index=original_series.index[1:] 189 190 predict = self.model.predict(1, pd.Series(self.timeseries.shape[0] 191 n_predict = inverse_diff(predict, self.t_s 192 print('模型预测:', '\n',n_predict 193 print('-------------------------------------------' 194 195 # #画图 196 plt.figure(figsize=(10, 4 197 plt.plot(self.t_s.index, self.t_s, label='actual' 198 plt.plot(n_predict.index, n_predict, label='predict' 199 # plt.xticks([] 200 plt.xticks(np.arange(0, self.df.shape[0], step=10 # 设置横坐标间距 201 plt.legend(['actual', 'predict'] 202 plt.xlabel('time(year' 203 plt.ylabel('SUNACTIVITY' 204 plt.title("真实值与预测值对比" 205 plt.show( 206 207 def Future_prediction(self,steps=2: 208 # 进行三步预测,并输出95%置信区间 209 210 # steps = 3 # 未来三期预测 211 forecast = self.model.get_forecast(steps=steps 212 table = pd.DataFrame(forecast.summary_frame( 213 214 # print(table.iloc[1] 215 table.iloc[0] = table.iloc[0] + self.t_s[-1] 216 # print(table.iloc[0, 0] 217 for i in range(steps - 1: 218 table.iloc[i + 1] = table.iloc[i + 1] + table.iloc[i, 0] 219 table.index = table.index.strftime('%Y' 220 print('--------------------------------------------------------------' 221 print(table 222 print('--------------------------------------------------------------'

TARMA

对应的调用方式:

1 import TARMA 2 ts=TARMA.Time_ARIMA(path='./M17.xlsx' #实例化对象(放入文件路径) 3 ts.Timing_Diagram( #时序图 4 ts.Diff_pre_sequence_test( #纯随机性检验 5 # 进行一阶差分 6 ts.Diff_operation( #进行一阶差分,当ADF检验合适即平稳且非白噪声序列不进行差分 7 ts.Diff_after_sequence_testing( #差分运算后的ADF检验 8 ts.ACF_and_PACF( #自相关图与偏自相关图 9 10 ts.Model_order_determination( #根据AIC准则与BIC准则进行机器定阶 11 12 #下面两种定阶方式二选一 13 ts.Model_building_artificial(order=(1,1,2 #模型构建(人工定阶,order中的三个参数为p,d,q 14 # ts.Model_building_machine( #模型构建(基于机器自己定阶 15 16 ts.Model_checking( #模型检验 17 ts.Model_prediction_accuracy( #模型可行性预测 18 ts.Future_prediction(steps=3 #未来数据预测默认为两期,steps参数可自定义

test

 

编程笔记 » 用Python语言进行时间序列ARIMA模型分析

赞同 (36) or 分享 (0)
游客 发表我的评论   换个身份
取消评论

表情
(0)个小伙伴在吐槽