[英]Forecasting with statsmodels
我有一个包含 5 年时间序列的 .csv 文件,每小时分辨率(商品价格)。 根据历史数据,我想创建第 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))
,这给出了以下输出:
现在,正如我所说,我没有任何统计技能,我几乎不知道我是如何得到这个输出的(基本上,改变第一行内的订单属性会改变输出),但“实际”预测看起来非常好,我想再延长一年(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 的旧版本 statsmodels。 您需要安装最新发布的 0.8.0 版,请参阅http://statsmodels.sourceforge.net/devel/install.html 。
我正在使用 Anaconda 并通过 pip 安装。
pip install -U statsmodels
SARIMAX 模型的结果类有许多有用的方法,包括预测。
data['Forecast'] = results.forecast(100)
将使用您的模型预测未来的 100 个步骤。
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/
阅读他讨论为什么这个模型没有给你你想要的部分。
“所以乍一看,这个模型似乎做得很好。但尽管看起来预测非常接近(毕竟线条几乎无法区分),但请记住,我们使用了无差异系列!该指数仅波动相对于总绝对值的每日小百分比。我们真正想要的是预测第一个差异,或每日移动。我们可以使用差异系列重新运行模型,或者添加一个"I" 术语到 ARIMA 模型(导致 (1, 1, 0) 模型)应该完成相同的事情。让我们尝试使用差分系列。”
要完成您想要做的事情,您需要对这些模型进行更多研究,并弄清楚如何设置数据格式以及哪种模型是合适的。 最重要的是了解您认为提供给模型的数据中包含哪些信息。 你的模型目前试图做的是说,“今天的价格是 45 美元。明天的价格是多少?” 就是这样。 它没有任何关于动量、波动性等的信息。这没什么好说的。
预测时尝试设置 dynamic = False
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.