ARIMA时序预测万能模板

早就知道ARIMA这个算法,但以前只会用来简单做个预测,对于参数选择,什么拖尾截尾一知半解,借着这次重新学一下ARIMA的原理,梳理一下使用ARIMA做时序预测的流程。

原理部分我是看了一篇知乎文章,讲的非常全面,我看了这篇文章感觉才懂,墙裂推荐给大家。感觉有这种博主愿意花费很多时间把一个算法讲的详细全面,真的很好!!!

https://www.zhihu.com/question/265009657/answer/3055557539

自己拿了一个手边的数据梳理了一下arima做预测的一个典型流程吧,这个代码模板无脑用。

总体流程分为:

1. 数据平稳性检测(原数据及差分数据)

2. 绘制安acf,pacf图初步判断数据适合AR模型还是MA模型还是ARIMA

这一步似乎可以省略?因为第三步做了超参优化可以直接帮助选择模型,p=0就是MA或则IMA模型,q=0就是AR或者ARI模型

3. 根据赤池信息准则和贝叶斯信息准则选择合适的(p,d,q)

4. 训练最佳的ARIMA模型并且进行预测

下面是代码:

导包

import matplotlib.pyplot as plt
import pandas as pd
from statsmodels.tsa.arima.model import ARIMA 
from statsmodels.tsa.stattools import adfuller
from statsmodels.graphics.tsaplots import plot_acf, plot_pacf

1. 查看数据平稳性 


def test_stationarity(timeseries):
    # 执行Dickey-Fuller测试,检测数据平稳性
    #p值小于0.05就可拒绝原假设(数据非平稳),也就是说我们认为数据是平稳的
    print('Results of Dickey-Fuller Test:')
    dftest = adfuller(timeseries, autolag='AIC')
    dfoutput = pd.Series(dftest[0:4], index=['Test Statistic', 'p-value', '#Lags Used', 'Number of Observations Used'])
    for key, value in dftest[4].items():
        dfoutput['Critical Value (%s)' % key] = value
    print(dfoutput)

def diff(df):
    # 绘制原数据、一阶差分、二阶差分折线图查看数据平稳性
    # 注 data_val是我原数据列名,需要根据自己数据调整
    df['first_diff'] = df['data_val'] - df['data_val'].shift(1)
    df['second_diff'] = df['first_diff']-df['first_diff'].shift(1)
    
    #绘图查看数据平稳性
    plt.figure()
    plt.plot(df['data_val'])
    plt.title('原数据')
    plt.show()
    
    plt.figure()
    plt.plot(df['first_diff'])
    plt.title('一阶差分结果')
    plt.show()
    
    plt.figure()
    plt.plot(df['second_diff'])
    plt.title('二阶差分结果')
    plt.show()
    
    #dickey fuller检测数据平稳性
    test_stationarity(df['data_val'])
    test_stationarity(df['first_diff'].iloc[1:]) #一阶差分第一个数据点为nan
    test_stationarity(df['second_diff'].iloc[2:]) #二阶查分前两个数据点为nan

2. 绘制ACF PACF图

关于ACF和PACF的分析,那篇知乎文章有很详细的分析

def plot_acf_and_pacf(df):
    '''
    Parameters
    ----------
    df : 时序数据,可以是dataframe,series,list

    对任意时间序列,当ACF图像呈现拖尾、且PACF图像呈现截尾状态时,当前时间序列适用AR模型,且
    PACF截尾的滞后阶数就是超参数p的理想值;
    对任意时间序列,当PACF图像呈现拖尾、且ACF图像呈现截尾状态时,当前时间序列适用MA模型,
    ACF截尾的滞后阶数就是超参数q的理想值
    对任意时间序列,当ACF图像和PACF图像都不呈现拖尾状态时,无论图像是否截尾,时间序列都
    适用于ARIMA模型,且此时ACF和PACF图像无法帮助我们确定p和q的具体值,但能确认p和q一
    定都不为0
    '''
    
    #计算Xt和Xt-1~Xt-30自相关系数
    plot_acf(df,lags=30)
    plt.show()
    
    plot_pacf(df,lags=30)
    plt.show()

3. 根据赤池信息准则和贝叶斯信息准则,寻找最佳的(p,d,q)来建立模型 。这里我挑选最佳参数是根据赤池信息准则和贝叶斯信息准则的均值,也可以自行查看输出的aic_bic_df来挑选最佳参数。

def param_optimization(df):
    # 尝试不同的ARIMA参数组合  
    models = []  #存储每一次的模型 
    aic_bic = []  #存储每一次的参数及aic bic结果
    aic_bic_min = 10000
    best_params = None
    
    p_values = range(0,5)  
    d_values = range(0, 3)  #d也可以通过差分结果得出
    q_values = range(0, 5)  
    df.index.feeq = 'MS'  #明确一下数据频率,可写可不写,不写模型会自动计算频率
    for p in p_values:  
        for d in d_values:  
            for q in q_values:  
                try:  
                    model = ARIMA(df, order=(p, d, q))  
                    fit_model = model.fit()  
                    aic = fit_model.aic  
                    bic = fit_model.bic  
                    models.append(fit_model)
                    aic_bic.append((p, d, q, aic, bic))
                    aic_bic_value = (aic+bic)/2
                    if aic_bic_value < aic_bic_min:
                        aic_bic_min = aic_bic_value
                        best_params=(p,d,q)
                      
                    print(f'ARIMA({p},{d},{q}): AIC={aic}, BIC={bic}')  
                except:  
                    continue  
      
    # 将AIC和BIC值转换为DataFrame以便查看  
    aic_bic_df = pd.DataFrame(aic_bic, columns=['p', 'd', 'q', 'AIC', 'BIC'])  
    print(aic_bic_df) 
    return best_params,aic_bic_df

4. 拟合模型进行预测

df = pd.read_excel(r'D:\data.xlsx',index_col=0)#读取数据
#根据自己数据可能需要做一些数据处理工作,我这里没写
df.set_index('data_time',inplace=True,drop=True)
#找最佳的p d q
best_params,aic_bic_df = param_optimization(df)
#拟合模型
model = ARIMA(df, order=(best_params[0],best_params[1],best_params[2]))  
model_fit = model.fit() 
#预测
pre = model_fit.forecast(steps=5)

好啦,就是这样,希望能帮到有需要的伙伴!

  • 5
    点赞
  • 9
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值