ARIMA预测(Python statsmodels)

3
我有一些时间序列数据,其中包含一些季节性趋势,我想使用ARIMA模型来预测这个系列在未来的行为。
为了预测我的感兴趣的变量(`log_var`)的行为,我已经取得了周、月和年度差异,然后将其作为输入到ARIMA模型中。
下面是一个例子。
exog = np.column_stack([df_arima['log_var_diff_wk'], 
                        df_arima['log_var_diff_mth'], 
                        df_arima['log_var_diff_yr']]) 

model = ARIMA(df_arima['log_var'], exog = exog, order=(1,0,1)) 
results_ARIMA = model.fit()  

我正在为几个不同的数据源进行此操作,在所有数据源中,我都看到了很好的结果,也就是说,如果我在训练数据上将log_varresults_ARIMA.fittedvalues绘制出来,它们非常匹配(我为每个数据源单独调整p和q,但d总是为0,因为我已经自己进行了差分)。
然而,我想要检查一下预测结果是什么样子的,为了做到这一点,我重新定义exog为“测试”数据集。例如,如果我在2014年1月1日至2016年1月1日期间对原始ARIMA模型进行训练,则“测试”集只需从2016年1月1日开始即可。
我的方法在某些数据源上表现良好(即我将预测值与已知值进行比较,趋势看起来合理),但在其他数据源上表现不佳,尽管它们都是相同类型的数据,只是来自不同的地理位置。在某些地方,它完全无法捕捉到在每年的同一日期在训练数据中反复出现的明显季节性趋势。ARIMA模型总是很好地拟合训练数据,只是在某些情况下预测结果完全没有用。
现在我在思考我是否正在按照正确的程序来预测ARIMA模型的值。我的方法基本上是:
exog = np.column_stack([df_arima_predict['log_val_diff_wk'], 
                        df_arima_predict['log_val_diff_mth'], 
                        df_arima_predict['log_val_diff_yr']])

arima_predict = results_ARIMA.predict(start=training_cut_date, end = '2017-01-01', dynamic = False, exog = exog)

这是使用ARIMA进行预测的正确方法吗?
如果是,那么在某些数据集中预测看起来非常好,而在另一些数据集中却很糟糕,即使ARIMA模型在两种情况下都能很好地拟合训练数据,我是否有办法尝试理解原因?

如果你对ARIMA不是很了解,那么你可能只是在过度拟合模型。过度拟合是机器学习中非常常见的问题,当你训练模型以完美匹配训练数据时,但在预测测试集时却无用(似乎就是正在发生的情况)。如果这是问题(很难说),你可以尝试调整参数,直到训练集的拟合足够好但不完美,ARIMA可能会更好地推广到测试数据集。 - Imanol Luengo
1个回答

0

我现在也遇到了类似的问题,但还没有完全搞清楚。似乎在Python中包含多个季节术语仍然有些棘手。R似乎具备这种能力,请参见此处。因此,我可以给您提供一个建议,就是暂时尝试使用R提供的更复杂功能(尽管如果您还不熟悉R,则可能需要大量投资时间)。

观察您对季节模式建模的方法,取第n阶差分得分并不会给您季节常数,而是一些表示您指定为季节相关的时间点之间差异的代表。如果这些差异很小,则对其进行校正可能对您的建模结果影响不大。在这种情况下,模型预测可能会相当不错。相反,如果差异很大,则包含它们很容易扭曲预测结果。这可能解释了您在建模结果中所看到的变化。因此,在概念上,您要做的是代表随时间变化的常数。

在上面提到的博客文章中,作者主张使用傅里叶级数来模拟每个时间段内的方差。NumPy和SciPy包都提供了计算快速傅里叶变换的例程。然而,作为一个非数学家,我发现很难确定快速傅里叶变换产生了适当的数字。
最终,我选择使用SciPy信号模块中的Welch信号分解形式。它返回您的时间序列的谱密度分析,从中可以推断出时间序列中各种频率的信号强度。
如果您确定谱密度分析中对应于您正在尝试解释的季节性频率的峰值,则可以使用它们的频率和振幅构建代表季节性变化的正弦波。然后,您可以将这些作为外生变量包含在您的ARIMA中,就像博客文章中的傅里叶项一样。

目前为止,这就是我自己所做的 - 现在我正在尝试弄清楚是否可以让statsmodels ARIMA过程在我的模型中使用这些正弦波作为外生变量来指定季节性趋势(文档指定它们不应该代表趋势,但嘿,一个人可以梦想,对吧?)编辑:Rob Hyneman的这篇博客文章也非常相关,并解释了包含傅里叶项的一些基本原理。

很抱歉我无法为您提供已被证明在Python中有效的解决方案,但我希望这能给您一些新的想法来控制那些令人讨厌的季节性差异。

简而言之:

  • 目前看来,Python 不太适合处理多个季节性项,R 可能是更好的解决方案(参见参考文献);

  • 使用差分得分来解释季节性趋势似乎不能捕捉到与季节性复发相关的恒定方差;

  • 在 Python 中实现这一点的方法之一可能是使用代表季节性趋势的傅里叶级数(也请参见参考文献),可以通过 Welch 信号分解等方式获得。如何将其作为外生变量有效地用于 ARIMA 是一个开放性问题。

祝你好运,

Evert

p.s.:如果我找到了在 Python 中使其工作的方法,我会更新的。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接