python statsmodels:帮助将ARIMA模型用于时间序列

时间:2015-07-29 02:12:42

标签: python statistics statsmodels

来自statsmodels的ARIMA给出了我输出的不准确答案。我想知道是否有人可以帮我理解我的代码有什么问题。

这是一个示例:

protected void Page_Load(object sender, EventArgs e)
{
    this.UnobtrusiveValidationMode =System.Web.UI.UnobtrusiveValidationMode.None;
}

其余代码设置了ARIMA模型。

import pandas as pd
import numpy as np
import datetime as dt
from statsmodels.tsa.arima_model import ARIMA

# Setting up a data frame that looks twenty days into the past,
# and has linear data, from approximately 1 through 20
counts = np.arange(1, 21) + 0.2 * (np.random.random(size=(20,)) - 0.5)
start = dt.datetime.strptime("1 Nov 01", "%d %b %y")
daterange = pd.date_range(start, periods=20)
table = {"count": counts, "date": daterange}
data = pd.DataFrame(table)
data.set_index("date", inplace=True)

print data

               count
date
2001-11-01   0.998543
2001-11-02   1.914526
2001-11-03   3.057407
2001-11-04   4.044301
2001-11-05   4.952441
2001-11-06   6.002932
2001-11-07   6.930134
2001-11-08   8.011137
2001-11-09   9.040393
2001-11-10  10.097007
2001-11-11  11.063742
2001-11-12  12.051951
2001-11-13  13.062637
2001-11-14  14.086016
2001-11-15  15.096826
2001-11-16  15.944886
2001-11-17  17.027107
2001-11-18  17.930240
2001-11-19  18.984202
2001-11-20  19.971603

正如您所看到的,数据在# Setting up ARIMA model order = (2, 1, 2) model = ARIMA(data, order, freq='D') model = model.fit() print model.predict(1, 20) 2001-11-02 1.006694 2001-11-03 1.056678 2001-11-04 1.116292 2001-11-05 1.049992 2001-11-06 0.869610 2001-11-07 1.016006 2001-11-08 1.110689 2001-11-09 0.945190 2001-11-10 0.882679 2001-11-11 1.139272 2001-11-12 1.094019 2001-11-13 0.918182 2001-11-14 1.027932 2001-11-15 1.041074 2001-11-16 0.898727 2001-11-17 1.078199 2001-11-18 1.027331 2001-11-19 0.978840 2001-11-20 0.943520 2001-11-21 1.040227 Freq: D, dtype: float64 附近不变,而不是增加。我在这里做错了什么?

(另一方面,由于某种原因,我无法将1等字符串日期传递到预测函数中。了解原因会很有帮助。)

1 个答案:

答案 0 :(得分:2)

TL; DR

您使用predict的方式会根据 差异内生变量不是对原始内生变量水平的预测。

您必须将predict的{​​{1}}方法输入以更改此行为:

typ='levels'

有关详细信息,请参见ARIMAResults.predict的文档。

一步一步

数据集

我们会加载您在MCVE中提供的数据:

preds = fit.predict(1, 30, typ='levels')

我们可能希望数据是自动相关的:

import io
import pandas as pd

raw = io.StringIO("""date        count
2001-11-01   0.998543
2001-11-02   1.914526
2001-11-03   3.057407
2001-11-04   4.044301
2001-11-05   4.952441
2001-11-06   6.002932
2001-11-07   6.930134
2001-11-08   8.011137
2001-11-09   9.040393
2001-11-10  10.097007
2001-11-11  11.063742
2001-11-12  12.051951
2001-11-13  13.062637
2001-11-14  14.086016
2001-11-15  15.096826
2001-11-16  15.944886
2001-11-17  17.027107
2001-11-18  17.930240
2001-11-19  18.984202
2001-11-20  19.971603""")

data = pd.read_fwf(raw, parse_dates=['date'], index_col='date')

enter image description here

模型和培训

我们为给定的设置from pandas.plotting import autocorrelation_plot autocorrelation_plot(data) 创建一个ARIMA Model对象,并使用fit方法在数据上训练它:

(P,D,Q)

它返回一个有趣的ARIMAResults对象。我们可以检查模型的质量:

from statsmodels.tsa.arima_model import ARIMA

order = (2, 1, 2)
model = ARIMA(data, order, freq='D')
fit = model.fit()

我们可以粗略估计残差的分布方式:

fit.summary()

                            ARIMA Model Results                              
==============================================================================
Dep. Variable:                D.count   No. Observations:                   19
Model:                 ARIMA(2, 1, 2)   Log Likelihood                  25.395
Method:                       css-mle   S.D. of innovations              0.059
Date:                Fri, 18 Jan 2019   AIC                            -38.790
Time:                        07:54:36   BIC                            -33.123
Sample:                    11-02-2001   HQIC                           -37.831
                         - 11-20-2001                                         
==============================================================================
                  coef    std err          z      P>|z|      [0.025     0.975]
------------------------------------------------------------------------------
const           1.0001      0.014     73.731      0.000       0.973      1.027
ar.L1.D.count  -0.3971      0.295     -1.346      0.200      -0.975      0.181
ar.L2.D.count  -0.6571      0.230     -2.851      0.013      -1.109     -0.205
ma.L1.D.count   0.0892      0.208      0.429      0.674      -0.318      0.496
ma.L2.D.count   1.0000      0.640      1.563      0.140      -0.254      2.254
                                    Roots                                    
==============================================================================
                   Real          Imaginary           Modulus         Frequency
------------------------------------------------------------------------------
AR.1            -0.3022           -1.1961j            1.2336           -0.2894
AR.2            -0.3022           +1.1961j            1.2336            0.2894
MA.1            -0.0446           -0.9990j            1.0000           -0.2571
MA.2            -0.0446           +0.9990j            1.0000            0.2571
------------------------------------------------------------------------------

enter image description here

预测

如果我们对模型感到满意,那么我们可以预测一些样本内或样本外数据。

这可以通过predict方法来完成,该方法默认情况下返回差分内生变量,而不是内生变量本身。要更改此行为,我们必须指定residuals = pd.DataFrame(fit.resid, columns=['residuals']) residuals.plot(kind='kde')

typ='levels'

那么我们的预测确实具有相同水平的训练数据:

enter image description here

此外,如果我们有兴趣也有置信区间,则可以使用forecast方法。

字符串参数

还可以向preds = fit.predict(1, 30, typ='levels') 提供字符串(如果要避免麻烦,请始终使用ISO-8601格式)或predict对象:

datetime

在StatsModels 0.9.0上可以正常工作:

preds = fit.predict("2001-11-02", "2001-12-15", typ='levels')