ARIMA(p,d,q)模型原理及其实现 --------python

            <div id="content_views" class="htmledit_views">
                <h3><a name="t0"></a>&nbsp;1.简介</h3> 

ARIMA模型(Autoregressive Integrated Moving Average model),差分整合移动平均自回归模型,又称整合移动平均自回归模型,时间序列预测分析方法之一。ARIMA(p,d,q)中,AR是"自回归",p为自回归项数;MA为"滑动平均",q为滑动平均项数,d为使之成为平稳序列所做的差分次数(阶数)。"差分"一词虽未出现在ARIMA的英文名称中,却是关键步骤。

2.模型原理

在描述ARIMA模型,那么就离不开AR、MA、ARMA模型,下面先阐述这两个模型。

2.1 AR模型(自回归)

自回归只适用于预测与自身前期相关的现象,数学模型表达式如下:

其中是当前值,是常数项,是阶数,是自相关系数,​​​​​是误差,同时

要符合正态分布。 

该模型反映了在t时刻的目标值值与前t-1~p个目标值之前存在着一个线性关系,即:

 2.2 MA模型(移动平均)

 移动平均模型关注的是自回归模型中的误差项的累加,数学模型表达式如下:

该模型反映了在t时刻的目标值值与前t-1~p个误差值之前存在着一个线性关系,即:

2.3 ARMA模型(自回归移动平均)

该模型描述的是自回归与移动平均的结合,具体数学模型如下:

2.4 ARIMA模型

基本原理:将数据通过差分转化为平稳数据,再将因变量仅对它的滞后值以及随机误差项的现值和滞后值进行回归所建立的模型。

AR是自回归,p为自回归项;MA为移动平均,q为移动平均项数,d为时间序列成为平稳时所做的差分次数,一般做一阶差分,很少做二阶差分。

2.5 ACF

​​​ACF 是一个完整的自相关函数,可为我们提供具有滞后值的任何序列的自相关值。简单来说,它描述了该序列的当前值与其过去的值之间的相关程度。时间序列可以包含趋势,季节性,周期性和残差等成分。ACF在寻找相关性时会考虑所有这些成分

2.6 PACF

偏自相关函数PACF 只描述观测值和其滞后项之间的直接关系,调整了其他较短滞后项的影响。

2.7 拖尾与截尾

截尾:在大于某个常数k后快速趋于0为k阶截尾

拖尾:始终有非零取值,不会在k大于某个常数后就恒等于零(或在0附近随机波动)

 例子:

3.定阶(p,d,q)

3.1 定d

因为AR(自回归)建立必须具有平稳性,所以在建立ARIMA模型也需要平稳性,使数据平稳性的方法可以讲数据进行差分处理,如一阶差分即t与t-1的差值,二阶差分为一阶差分基础上再进行一次差分,使数据平稳后的差分次数即为我们要定的参数d

3.2 方法① 定p,q
  • 若PACFp阶段后截尾,则截尾的阶数即为模型所确定的参数p。
  • 若ACFq阶段后截尾,则截尾的阶数即为模型所确定的参数q。

3.3 方法② 定p,q

采用AIC或BIC原则,模型中AIC或BIC值越小,模型就越好。

4.假设检验

下面介绍在用python实现ARIMA模型使用到的假设检验。

4.1单位根检验(ADF)

在建立ARIMA模型的前,要讲将数据平稳化,即需要对数据进行差分处理,一般进行一节差分即可,一般一节差分就可以通过检验,如果一阶不通过,就再进行一次差分,即二阶差分,但不是差分的次数越多越好,它可能会导致数据信息的损失。检验数据平不平稳,第一种方法可以通过直接观察差分后的折线图。第二种方法就是通过假设检验,即单位根检验:

注:这里没有详细描述检验原理,只是简单介绍其原假设与备择假设,感兴趣可查找相关资料。

4.2残差正态性检验

完成模型建立,需要对模型的残差进行正态性检验,python中scipy库中的stats类提供了一个 normaltest函数,用于检验数据是否符合正太性:

残差是否符合正态性不一定要用假设检验,也可以观察残差的qq图,当qq图的散点位于一条直线时候说明是符合正态分布,同时也可以绘制残差频数直方图,下面会介绍检验、qq图、频数直方图实现代码。

 4.3残差序列独立性检验

一个较好的ARIMA模型,残差序列之间是独立性的,检验德宾-沃森(Durbin-Watson)检验简称D-W检验,是目前检验自相关性最常用的方法,但它只适用于检验一阶自相关性。 先通过公式计算出DW值,再根据样本容量n和解释变量数目k查分布表,得到临界值dl和du,然后判断是否自相关,当DW值等于2左右时,模型不存在一阶自相关

注:这里没有详细描述检验原理,只是简单介绍检验判别方法,感兴趣可查找相关资料。

5.建模基本流程

6.python实现ARIMA

这次建模所用到的库如下代码,若还没有安装,在cmd窗口输入 pip install 库名   即可安装。


 
 
  1. import pandas as pd
  2. import numpy as np
  3. from matplotlib import pyplot as plt
  4. import matplotlib
  5. import seaborn as sns
  6. from statsmodels.tsa.arima_model import ARIMA
  7. import statsmodels as sm
  8. from scipy import stats
AI写代码
6.1数据展示

这是笔者的数据,只要构造好这个dataframe数据类型就可以继续下面的步骤,该数据用变量data接受,下面的代码针对data变量都是针对这个数据集

6.2缺失值处理
data.info()
 
 
AI写代码

发现数据集存在缺失值,对于时间序列数据缺失值不能简单的使用全体数据均值、中位数、众数处理,最常用的方法有前后加权均值法、线性插值法、n最近邻均值法填充,本次采用n=2的n最近邻均值法填充,比如n取2,则用t-2,t-1,t+1,t+2时刻的平均值来填充缺失的t时刻的值,代码实现如下:


 
 
  1. #找出有缺失值的行 data[["data"]].isnull().T.any().values
  2. def knm( df,n):
  3. #找出缺失值的行
  4. temp = df.isnull().T. any().values
  5. temp_df = df.copy()
  6. for i in range( len(temp)):
  7. if temp[i] == True:
  8. if i < n- 1: #前n个
  9. temp_df.loc[i, "data"] = df.loc[i:i+n, "data"].mean()
  10. elif i > len(temp) - 1 -n: #后n个
  11. temp_df.loc[i, "data"] = df.loc[i-n:i, "data"]
  12. else:
  13. print(df.loc[i-n:i+n, "data"])
  14. temp_df.loc[i, "data"] = df.loc[i-n:i+n, "data"].mean()
  15. print(i-n,i+n+ 1)
  16. return temp_df
  17. not_miss = knm(data[[ "data"]], 2)
  18. data[ "data"] = not_miss.values
AI写代码
 6.3数据可视化展示

 
 
  1. plt.plot(data.iloc[:, 1])
  2. plt.hist(data.iloc[:, 1],bins= 20)
AI写代码

6.4数据平稳化

 
 
  1. data[ "diff_1"] = data[ "data"].diff( 1) #一阶差分
  2. data[ "diff_2"] = data[ "data"].diff( 1) #二阶差分
  3. #分别画出ACF(自相关)和PACF(偏自相关)图像
  4. from statsmodels.graphics.tsaplots import plot_acf
  5. from statsmodels.graphics.tsaplots import plot_pacf
  6. def diff( df,col):
  7. font = { "size": 15,
  8. "family": "fangsong"}
  9. matplotlib.rc( "font",**font)
  10. matplotlib.rcParams[ 'axes.unicode_minus']= False
  11. df[ "diff_1"] = df[col].diff( 1) #一阶差分
  12. df[ "diff_2"] = df[ "diff_1"].diff( 1) #二阶差分
  13. #平稳数据折线图
  14. plt.figure(figsize=( 12, 8))
  15. plt.subplot( 3, 1, 1)
  16. plt.plot(df[col].values,label= "源数据")
  17. plt.xlim( 0, 120)
  18. plt.legend()
  19. plt.subplot( 3, 1, 2)
  20. plt.plot(df[ "diff_1"].values,c= "darkgreen",label= "一阶差分")
  21. plt.plot([ 0, 120],[ 0, 0], "--",c = "grey")
  22. plt.xlim( 0, 120)
  23. plt.legend()
  24. plt.subplot( 3, 1, 3)
  25. plt.plot(df[ "diff_2"].values,c= "tomato",label= "二阶差分")
  26. plt.plot([ 0, 120],[ 0, 0], "--",c = "grey")
  27. plt.xlim( 0, 120)
  28. plt.legend()
  29. plt.show()
  30. #ACF PACF
  31. print( "-"* 50, "未平稳数据ACF与PACF", "-"* 50)
  32. fig = plt.figure(figsize=( 12, 8))
  33. ax1 = fig.add_subplot( 211)
  34. fig = plot_acf(df[col], lags= 40,ax = ax1)
  35. ax2 = fig.add_subplot( 212)
  36. plot_pacf(df[col], lags= 40,ax = ax2)
  37. plt.show()
  38. #一阶差分后的ACF PACF
  39. print( "-"* 50, "一阶差分数据ACF与PACF", "-"* 50)
  40. fig = plt.figure(figsize=( 12, 8))
  41. ax1 = fig.add_subplot( 211)
  42. fig = plot_acf(df[ "diff_1"][ 1:].values, lags= 40,ax = ax1)
  43. ax2 = fig.add_subplot( 212)
  44. plot_pacf(df[ "diff_1"][ 1:], lags= 40,ax = ax2)
  45. plt.show()
  46. diff(data, "data")
AI写代码

一阶自相关与偏相关图都呈现出拖尾现象,无法从这两图确定p与q。

6.5数据平稳性检验 单位根检验 

 
 
  1. #未差分平稳性检测(ADF检验、单位根检验)
  2. from statsmodels.tsa.stattools import adfuller as ADF
  3. print( u'原始序列的ADF检验结果为:', ADF(data[ "data"]))
  4. #返回值依次为adf、pvalue、usedlag、nobs、critical values、icbest、regresults、resstore p<0.05时表示稳定
AI写代码


 
 
  1. #一阶差分平稳性检测(ADF检验、单位根检验)
  2. from statsmodels.tsa.stattools import adfuller as ADF
  3. print( u'一阶差分序列的ADF检验结果为:', ADF(data[ "diff_1"][ 1:]))
  4. #返回值依次为adf、pvalue、usedlag、nobs、critical values、icbest、regresults、resstore p<0.05时表示稳定
AI写代码

一阶差分单位根检验p值<0.05,原始序列p值>0.05,于是ARIMA中的参数d定为1。

6.6根据bic/aic指标定p、q

 
 
  1. #定阶
  2. # pmax = int(len(df["失业率"])/10) #一般阶数不超过length/10
  3. # qmax = int(len(df["失业率"])/10) #一般阶数不超过length/10
  4. pmax = 5
  5. qmax = 5
  6. bic_matrix = [] #bic矩阵
  7. for p in range(pmax+ 1):
  8. tmp = []
  9. for q in range(qmax+ 1): #存在部分报错,所以用try来跳过报错。
  10. try:
  11. tmp.append(ARIMA(data[ "data"],order=(p, 1,q)).fit().bic)
  12. except:
  13. tmp.append( None)
  14. bic_matrix.append(tmp)
  15. bic_matrix = pd.DataFrame(bic_matrix) #从中可以找出最小值
  16. p,q = bic_matrix.stack().idxmin()
  17. # #先用stack展平,然后用idxmin找出最小值位置。
  18. print( u'BIC最小的p值和q值为:%s、%s' %(p,q))
AI写代码

 
 
  1. #定阶
  2. # pmax = int(len(df["失业率"])/10) #一般阶数不超过length/10
  3. # qmax = int(len(df["失业率"])/10) #一般阶数不超过length/10
  4. pmax = 5
  5. qmax = 5
  6. aic_matrix = [] #bic矩阵
  7. for p in range(pmax+ 1):
  8. tmp = []
  9. for q in range(qmax+ 1): #存在部分报错,所以用try来跳过报错。
  10. try:
  11. tmp.append(ARIMA(data[ "data"],order=(p, 1,q)).fit().aic)
  12. except:
  13. tmp.append( None)
  14. aic_matrix.append(tmp)
  15. aic_matrix = pd.DataFrame(bic_matrix) #从中可以找出最小值
  16. p,q = bic_matrix.stack().idxmin()
  17. # #先用stack展平,然后用idxmin找出最小值位置。
  18. print( u'AIC最小的p值和q值为:%s、%s' %(p,q))
AI写代码

根据aic/bic最小原则都筛选出p=5,q=3。

6.7模型拟合 AIRMA(5,1,3)

 
 
  1. arima513 = ARIMA(data[ "data"],order=( 5, 1, 3)).fit()
  2. arima513.summary2()
AI写代码

 

6.7模型检验

 
 
  1. resid=arima513.resid #残差
  2. plt.figure(figsize=( 12, 8))
  3. plt.plot(resid)
AI写代码

6.7.1残差正态性检验
stats.normaltest(resid)#检验序列残差是否为正态分布    pvalue=0.00028625258929196876   <  0.05  拒绝原假设 认为残差符合正太分布
 
 
AI写代码

 

p<0.05,接受备择假设,认为残差具有正态性


 
 
  1. stats.probplot(resid, dist= "norm", plot=plt)
  2. plt.show()
  3. plt.hist(resid,bins= 50)
  4. plt.show()
AI写代码

 

qq图散点基本在直线上,同时直方图也呈现正态性。

6.7.2残差序列自相关 (残差序列是否独立)

 
 
  1. from statsmodels.stats.stattools import durbin_watson
  2. durbin_watson(arima513.resid.values) ##DW检验:靠近2——正常;靠近0——正自相关;靠近4——负自相关
AI写代码

 DW值非常靠近2,说明序列不具有相关性。

7.绘制原数据和预测数据对比图

 
 
  1. # 绘制原数据和预测数据对比图
  2. arima513.plot_predict(dynamic= False)
  3. plt.show()
AI写代码

通过观察预测值与实际值折线图,可以直观看出该模型拟合程度不怎么好,待优化

 

​​

参考:https://blog.csdn.net/weixin_49583390/article/details/121914303

03-11
### ARIMA模型概述 ARIMA(AutoRegressive Integrated Moving Average),即自回归积分滑动平均模型,是一种用于时间序列数据分析的强大工具[^1]。该模型通过结合三个主要组成部分来描述时间序列的行为: - **自回归 (AR)** 部分表示当前观测值与过去若干期的观测值之间的线性关系; - **差分 (I, Integration)** 是指为了使原始非平稳的时间序列变得平稳而进行的一系列操作; - **移动平均 (MA)** 描述了当前误差项与其他各时期随机扰动的影响。 #### 参数说明 ARIMA(p,d,q),其中p代表自回归部分的最大滞后长度;d为差分次数;q则是移动平均过程中的最大滞后期数。这三个参数的选择对于构建有效的ARIMA模型至关重要[^3]。 ### 应用实例 在实际应用中,ARIMA已被证明适用于多种类型的预测任务,尤其是在经济金融领域内的销售量预估、股票价格走势判断等方面表现出色[^2]。此外,在互联网行业里也常被用来做网站访问量趋势分析等。 具体到实施层面,当面对一个新的时间序列数据集时,通常会先绘制出这组数据随时间变化的趋势图以便直观感受是否存在明显的周期性和稳定性特点。如果发现原序列为非稳态,则需对其进行适当阶次(d)的一阶或多阶差分化处理直至达到稳定状态为止[^4]。 ```python import pandas as pd from statsmodels.tsa.arima.model import ARIMA # 假设我们有一个名为dataframe的数据框,里面有一列time_series_data存储着我们要建模的时间序列数值 model = ARIMA(dataframe['time_series_data'], order=(5,1,0)) results = model.fit() print(results.summary()) ``` 此段Python代码展示了如何使用`statsmodels`库下的`ARIMA`函数创建并拟合一个简单的ARIMA(5,1,0)模型给定输入时间为索引且含有单变量目标列‘time_series_data’的数据表对象"dataframe".
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值