使用 statsmodels 进行预测

Posted

技术标签:

【中文标题】使用 statsmodels 进行预测【英文标题】:Forecasting with statsmodels 【发布时间】:2016-12-08 00:11:55 【问题描述】:

我有一个 .csv 文件,其中包含一个 5 年的时间序列,具有每小时分辨率(商品价格)。根据历史数据,我想创建第 6 年的价格预测。

我在 www 上阅读了几篇关于这类程序的文章,我的代码基本上基于那里发布的代码,因为我在 Python(尤其是 statsmodels)和统计方面的知识最多。

这些是链接,有兴趣的人:

http://www.seanabu.com/2016/03/22/time-series-seasonal-ARIMA-model-in-python/

http://www.johnwittenauer.net/a-simple-time-series-analysis-of-the-sp-500-index/

首先,这是 .csv 文件的示例。在这种情况下数据以月分辨率显示,它不是真实数据,只是随机选择的数字在这里举个例子(在这种情况下,我希望一年足以能够对第二年进行预测;如果没有,完整的 csv 文件可用):

              Price
2011-01-31    32.21
2011-02-28    28.32
2011-03-31    27.12
2011-04-30    29.56
2011-05-31    31.98
2011-06-30    26.25
2011-07-31    24.75
2011-08-31    25.56
2011-09-30    26.68
2011-10-31    29.12
2011-11-30    33.87
2011-12-31    35.45

我目前的进度如下:

读取输入文件并将日期列设置为日期时间索引后,使用以下脚本对可用数据进行预测

model = sm.tsa.ARIMA(df['Price'].iloc[1:], order=(1, 0, 0))  
results = model.fit(disp=-1)  
df['Forecast'] = results.fittedvalues  
df[['Price', 'Forecast']].plot(figsize=(16, 12))  

,它给出以下输出:

现在,正如我所说,我没有统计技能,我几乎不知道我是如何得到这个输出的(基本上,改变第一行中的 order 属性会改变输出),但是“实际' 预测看起来不错,我想再延长一年(2016 年)。

为此,在数据框中创建了额外的行,如下所示:

start = datetime.datetime.strptime("2016-01-01", "%Y-%m-%d")
date_list = pd.date_range('2016-01-01', freq='1D', periods=366)
future = pd.DataFrame(index=date_list, columns= df.columns)
data = pd.concat([df, future])

最后,当我使用statsmodels的.predict函数时:

data['Forecast'] = results.predict(start = 1825, end = 2192, dynamic= True)  
data[['Price', 'Forecast']].plot(figsize=(12, 8))

我得到的预测是一条直线(见下文),这看起来根本不像预测。此外,如果我将现在从第 1825 天到第 2192 天(2016 年)的范围扩大到整个 6 年时间跨度,则预测线是整个时期(2011-2016)的直线。

我也尝试使用 'statsmodels.tsa.statespace.sarimax.SARIMAX.predict' 方法,它解释了季节性变化(在这种情况下是有意义的),但我得到了一些关于 'module' 的错误没有属性“SARIMAX”。但这是次要问题,如果需要,会详细说明。

我在某个地方失去了控制,我不知道在哪里。谢谢阅读。干杯!

【问题讨论】:

我也有类似的问题。你能解决吗?谢谢 不,我还没有解决。由于工作中断,我在某个时候放弃了它,再也没有回到这个.. 【参考方案1】:

在预测时尝试 set dynamic = False

【讨论】:

能否请您详细说明您的答案,而不是提供一行答案。确实如此。不帮助 OP 进行故障排除。【参考方案2】:

ARIMA(1,0,0) 是一个单周期自回归模型。所以它是一个遵循这个公式的模型:

这意味着时间段 t 中的值等于某个常数 (phi_0) 加上通过拟合 ARMA 模型确定的值 (phi_1) 乘以上一期间 r_(t-1) 中的值,再加上白噪声误差项 (a_t)。

您的模型只有 1 个时期的记忆,因此当前预测完全由上时期的 1 值决定。这不是一个非常复杂的模型。它并没有对所有先前的值做任何花哨的事情。它只是取昨天的价格,乘以某个值并加上一个常数。你应该期望它很快达到平衡,然后永远保持在那里。

上图中的预测之所以看起来如此出色,是因为它只是向您展示了数百个 1 期间的预测,这些预测随着每个新时期的到来而重新开始。它并没有像您可能认为的那样显示长期预测。

查看您发送的链接:

http://www.johnwittenauer.net/a-simple-time-series-analysis-of-the-sp-500-index/

阅读他讨论为什么这个模型不能给你想要的东西的部分。

“所以乍一看,这个模型似乎做得很好。但虽然看起来预测真的很接近(毕竟线条几乎无法区分),但请记住我们使用的是未差分系列!索引相对于总绝对值,每天只波动很小的百分比。我们真正想要的是预测第一个差异,或日常移动。我们可以使用差异序列重新运行模型,或者在 ARIMA 模型中添加一个“I”项(生成 (1, 1, 0) 模型),它应该可以完成同样的事情。让我们尝试使用差分序列。”

要完成您想做的事情,您需要对这些模型进行更多研究,并弄清楚如何格式化您的数据,以及哪种模型是合适的。最重要的是知道您认为输入模型的数据中包含哪些信息。你的模型目前试图做的是说,“今天的价格是 45 美元。明天的价格是多少?”而已。它没有关于动量、波动性等的任何信息。这没什么好说的。

【讨论】:

【参考方案3】:

听起来您正在使用不支持 SARIMAX 的旧版 statsmodels。您需要安装最新发布的 0.8.0 版,请参阅 http://statsmodels.sourceforge.net/devel/install.html

我正在使用 Anaconda 并通过 pip 安装。

pip install -U statsmodels

SARIMAX 模型的结果类有许多有用的方法,包括预测。

data['Forecast'] = results.forecast(100)

将使用您的模型预测未来 100 步。

【讨论】:

如果你想在样本外进行预测,并且你有外生变量,你必须首先提供这些预测(你可能没有)。 向 Geoff D 和 fccoelho 大喊。文档中的语言令人困惑。看到这个终于明白了。

以上是关于使用 statsmodels 进行预测的主要内容,如果未能解决你的问题,请参考以下文章

使用 statsmodels 进行预测

使用 statsmodels 进行 ARMA 样本外预测

使用 statsmodels 进行 Holt-Winters 时间序列预测

Python statsmodels ARIMA 预测

Statsmodels ARIMA - 使用预测()和预测()的不同结果

Python:使用 Statsmodels 预测 y 值 - 线性回归