使用statsmodels进行预测

时间:2016-08-02 14:53:07

标签: python forecasting statsmodels

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

我已经在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))  

,它给出了以下输出:

5-year timeseries, hourly resolution data

现在,正如我所说,我没有统计技能,我几乎不知道我是如何得到这个输出的(基本上,改变第一行内的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'方法,它考虑了季节性变化(在这种情况下是有意义的),但我得到一些关于'模块'没有属性' SARIMAX'。但这是次要问题,如果需要,还会详细介绍。

forecast output

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

3 个答案:

答案 0 :(得分: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个步骤。

答案 1 :(得分:3)

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

enter image description here

这意味着时间段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/

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

"所以乍一看似乎这个模型做得很好。但是虽然预测看起来非常接近(毕竟这些线几乎无法区分),但请记住我们使用的是无差异系列!该指数仅相对于总绝对值每日波动一小部分。我们真正想要的是预测第一个差异,或预测日常行动。我们可以使用差异系列重新运行模型,或者添加" I" ARIMA模型的术语(产生(1,1,0)模型)应该完成同样的事情。让我们尝试使用差异系列。"

要做您正在尝试做的事情,您需要对这些模型进行更多研究,并找出如何格式化数据以及适合的模型。最重要的是知道您认为哪些信息包含在您输入模型的数据中。你的模特目前正在尝试做的是,"今天的价格是45美元。明天的价格是多少?"就是这样。它没有关于动量,波动性等的任何信息。这没什么可说的。

答案 2 :(得分:-1)

在预测时尝试设置动态= False