• 自动 ARIMA 超参数搜索


    一、介绍

            

            这种用于自动超参数搜索进行预测的开发方法可能会花费大量时间,但它可以带来回报,因为当您找到预测模型的最佳参数时,它将节省时间并提高预测的精度。此外,手动尝试可能会花费您最多的时间,但这种方法在某些情况下可能会有所帮助,请记住,理解为什么我们应该在预测模型中使用精确的参数对于更好地理解业务问题至关重要。尽管如此,这种方法可以缩短您的探索时间并帮助您更好地理解您的问题。

            在这篇博客中,我将介绍自动搜索 (S)ARIMA 预测模型关键参数的方法。我们将在 (S)ARIMA 预测模型中调整的超参数是季节性参数 (S)、自回归参数 (AR)、差分参数 (I) 和移动平均值 (MA)。如果需要,您可以在我之前的博客中阅读有关此参数的更多信息(此处)。

    二、CO2 数据示例

            我们将检查并绘制过去 50 年二氧化碳排放时间序列的趋势和季节性,由于冬季供暖期,我们看到了增加的趋势和清晰的季节性模式(完整代码和数据可在此处获取

    1. import pandas as pd
    2. import numpy as np
    3. from statsmodels.tsa.seasonal import STL
    4. import matplotlib.pyplot as plt
    5. from statsmodels.tsa.stattools import adfuller
    6. import statsmodels.api as sm
    7. plt.rc('figure',figsize=(10,6))
    8. plt.rc('font',size=13)
    9. stl = STL(co2, seasonal=7)
    10. res = stl.fit()
    11. fig = res.plot()

    CO2数据分解

    在使用创建的函数绘制差分时间序列的滚动平均值(12 个数据点)和标准差后,我们应该检查多年来二氧化碳排放量的平稳性。

    1. def test_stationarity(timeseries, rolling=12):
    2. #Determing rolling statistics
    3. rolmean = timeseries.rolling(rolling).mean()
    4. rolstd = timeseries.rolling(rolling).std()
    5. #Plot rolling statistics:
    6. plt.figure(figsize=(10, 5))
    7. orig = plt.plot(timeseries, color='blue',label='Original')
    8. mean = plt.plot(rolmean, color='red', label='Rolling Mean')
    9. std = plt.plot(rolstd, color='black', label = 'Rolling Std')
    10. plt.title('Power consumption Old data')
    11. plt.xlabel('Time - periods(30s)')
    12. plt.ylabel('Power consumption in Watts')
    13. plt.legend(loc='best')
    14. plt.title('Rolling Mean & Standard Deviation')
    15. plt.show()
    16. #Perform Dickey-Fuller test:
    17. print ('Results of Dickey-Fuller Test:')
    18. dftest = adfuller(timeseries, autolag='AIC')
    19. dfoutput = pd.Series(dftest[0:4], index=['Test Statistic','p-value','#Lags Used','Number of Observations Used'])
    20. for key,value in dftest[4].items():
    21. dfoutput['Critical Value (%s)'%key] = value
    22. print (dfoutput)
    23. if dfoutput['p-value'] < 0.05:
    24. print('The time series is stationary at 95% level of confidence')
    25. else:
    26. print('The time series is not stationary at 95% level of confidence')
    27. co2_diff = co2 - co2.shift(1)
    28. co2_diff = co2_diff.dropna()
    29. test_stationarity(co2_diff, rolling=12)

    差分 C02 数据是平稳的。

    在进行自动 arima 搜索之前,我们将检查 40 个时间点的相关图,以了解数据如何跨滞后相关,由此我们可以确认高 AR 参数以及强季节性模式(偏相关,捕获所有其他变量回归后的残差)。

    1. fig, axes = plt.subplots(1, 2, figsize=(15,4))
    2. fig = sm.graphics.tsa.plot_acf(co2,
    3. lags=40,
    4. ax=axes[0])
    5. fig = sm.graphics.tsa.plot_pacf(co2,
    6. lags=40,
    7. ax=axes[1])

    C02 数据的相关图。

    三、自动调节

            在代码的下一部分中,我们创建了 p (AR)、d(I) 和 q(MA) 参数的几种组合。为了放宽搜索范围,我们将季节性 (s) 参数定义为 12,因为我们确信存在年度模式。为了评估模型的优点,我们使用 Akaike 信息标准 (aic)。该标准对于某些数据的统计模型至关重要,通过计算 k(模型中估计参数的数量)与 L(模型似然函数的最大值)之间的差异。这意味着具有最佳 AIC 的模型将具有最佳似然值和尽可能最少的参数数量,从而使模型简单高效(简约),从而实现最佳性能。模型的AIC值如下:

    AIC=2k−2ln(L)

    1. import itertools
    2. import warnings
    3. warnings.filterwarnings('ignore')
    4. # Grid Search
    5. p = d = q = range(0,3) # p, d, and q can be either 0, 1, or 2
    6. pdq = list(itertools.product(p,d,q)) # gets all possible combinations of p, d, and q
    7. p2 = d2 = q2 = range(0, 2) # second set of p's, d's, and q's for seasonal parameters
    8. pdq2 = list(itertools.product(p2,d2,q2)) # similar to code above but for seasonal parameters
    9. s = 12 # here I use twelve but the number here is representative of the periodicity of the seasonal cycle
    10. pdqs2 = [(c[0], c[1], c[2], s) for c in pdq2]
    11. combs = {}
    12. aics = []
    13. # Grid Search Continued
    14. for combination in pdq:
    15. for seasonal_combination in pdqs2:
    16. try:
    17. model = sm.tsa.statespace.SARIMAX(co2, order=combination, seasonal_order=seasonal_combination,
    18. enforce_stationarity=True,
    19. enforce_invertibility=True)
    20. model = model.fit(disp=False)
    21. combs.update({model.aic : [combination, seasonal_combination]})
    22. aics.append(model.aic)
    23. except:
    24. continue
    25. best_aic = min(aics)

            现在我们可以看到哪些预测超参数可以提供最佳预测。

    1. print('best aic is: ', round(best_aic, 3))
    2. print(40*'==')
    3. print ('ARIMA parameters: ', '\n', 'AR: ', combs[best_aic][0][0], '\n', 'I: ',combs[best_aic][0][1], '\n', 'MA: ',combs[best_aic][0][2])
    4. print('Seasonal parameters:', combs[best_aic][1])

            自动选择的参数由最佳AI​​C值决定。

            恭喜!有了这个超参数,我们可以进行训练测试分割并对测试集进行预测,然后比较预测和测试结果。

    四、使用选定的超参数进行预测

            创建train-test split函数后,我们进行实际预测:

    1. def train_test_split(timeseries, lags_for_prediction=12):
    2. split=len(timeseries)-lags_for_prediction
    3. train=timeseries[:split]
    4. test=timeseries[split:]
    5. return train, test
    6. train_series, test_series = train_test_split(co2, 12)

            检查模型优良性的好方法是绘制预测数据与测试数据的图。在实际应用中,真正的预测将更多地涉及未来,但这一步确保我们拥有一个好的模型。

    1. def forecasting (p,d,q, season, lags_for_forecast, train_series):
    2. model = sm.tsa.statespace.SARIMAX(train_series, order=(p,d,q), seasonal_order=(p,d,q,season),
    3. simple_differencing=0, #if True time series provided as endog is literally differenced and an ARMA model is fit to the resulting new time series
    4. enforce_stationarity=True,
    5. enforce_invertibility=False)
    6. fitted = model.fit(disp=-1)
    7. # Forecast
    8. forecast = fitted.forecast(lags_for_forecast)
    9. # Plot
    10. plt.figure(figsize=(12,5), dpi=100)
    11. plt.plot(train_series, color='blue', label='train')
    12. plt.plot(test_series, color='green', label='test', alpha=0.6)
    13. plt.plot(forecast, color='red', label='forecast')
    14. plt.title('Forecast vs Actuals')
    15. plt.legend(loc='upper left', fontsize=8)
    16. plt.show()
    17. RSS=np.sqrt(sum(forecast.values-test_series.values.reshape(-1))**2)/lags_for_forecast
    18. print("\n", '\033[1m' +'Root Squared Error (RSS) of SARIMAX model(p,d,q)(p,d,q,s)' + '\033[0m',(p,d,q),season,':', round(RSS, 3),"\n")
    19. print(fitted.summary())
    20. forecasting (2,1,1, 12, 12, train_series)

    预测数据与测试数据。

            正如我们所看到的,自动调整效果非常好。statsmodels 的摘要选项使我们能够更深入地了解参数的统计显着性。非常小的均方根误差 (0.313) 为我们提供了额外的保证,即我们拥有可靠且良好的模型。就这样了。在某些情况下,旧的传统 ARIMA 可以击败复杂的 LSTM :)

  • 相关阅读:
    STM32 寄存器操作 systick 滴答定时器 与中断
    QT---day3---9.19
    python-flask笔记
    Python程序设计--学生管理系统-面向对象项目
    【Vue】修饰符&表单提交方式&自定义组件
    跑马灯带你深入浅出TextView的源码世界
    js手写红绿灯(带优化版)
    ROS笔记之visualization_msgs-Marker学习
    Python gdal读取MODIS遥感影像并结合质量控制QC波段掩膜数据
    EL表达式内置对象cookie
  • 原文地址:https://blog.csdn.net/gongdiwudu/article/details/134490427