统计模型 SARIMAX 预测
stasmodels SARIMAX predictions
我正在尝试了解如何使用 statsmodels
.
验证 ARIMAX 模型提前 > 1 步
我的理解是 results.get_prediction(start=, dynamic=)
api 执行此操作,但我无法理解它是如何工作的。我的训练数据由 15T 频率的本地化 DateTimeIndex (tz='Sydney\Australia') 索引。我想预测“2019-02-04 00:00:00+1100”的一整天,使用前一步预测到“2019-02-04 06:00:00+1100”之前预测的内生值剩下的时间。
下面的代码是否正确?似乎 statsmodel 将开始转换为时间戳并将动态视为频率的倍数,因此这应该使用提前 1 步开始模拟,直到 06:00 然后使用先前预测的内生值。结果看起来不太好,所以我想确认这是一个模型问题,而不是我的诊断不正确。
dt = '2019-02-04'
predict = res.get_prediction(start='2019-02-04 00:00:00+11:00')
predict_dy = res.get_prediction(start='2019-02-04 00:00:00+11:00', dynamic=4*6)
fig = plt.figure(figsize=(10,10)) ax = fig.gca()
y_train[dt].plot(ax=ax, style='o', label='Observed')
predict.predicted_mean[dt].plot(ax=ax, style='r--', label='One-step-ahead forecast')
predict_dy.predicted_mean[dt].plot(ax=ax, style='g', label='Dynamic forecast')
It seems statsmodel converts the start to a TimeStamp
是的,如果您给它一个字符串值,那么它会尝试将其映射到数据集中的索引(如时间戳)。
and treats dynamic as a multiple of the freq
但这是不正确的。 dynamic
是 start
的整数偏移量。因此,如果 dynamic=0
,则意味着动态预测从 start
开始,而如果 dynamic=1
,则意味着动态预测从 start+1
.
开始
我不太清楚你的示例中发生了什么(或者你认为你生成的预测不太好),所以这里描述了 dynamic
的工作原理,可能会有所帮助:
这是一个可能有助于解释事物运作方式的示例。本练习的几个关键点是:
- 我设置
endog
的所有元素都等于1
- 这是一个参数为 0.5 的 AR(1) 模型。这意味着如果我们知道 y_t,那么 y_t+1 的预测等于 0.5 * y_t.
现在,示例代码是:
ix = pd.date_range(start='2018-12-01', end='2019-01-31', freq='D')
endog = pd.Series(np.ones(len(ix)), index=ix)
mod = sm.tsa.SARIMAX(endog, order=(1, 0, 0), concentrate_scale=True)
res = mod.smooth([0.5])
p1 = res.predict(start='January 1, 2019', end='January 5, 2019').rename('d=False')
p2 = res.predict(start='January 1, 2019', end='January 5, 2019', dynamic=0).rename('d=0')
p3 = res.predict(start='January 1, 2019', end='January 5, 2019', dynamic=1).rename('d=2')
print(pd.concat([p1, p2, p3], axis=1))
这给出:
d=False d=0 d=2
2019-01-01 0.5 0.50000 0.5000
2019-01-02 0.5 0.25000 0.5000
2019-01-03 0.5 0.12500 0.2500
2019-01-04 0.5 0.06250 0.1250
2019-01-05 0.5 0.03125 0.0625
第一列 (d=False) 是默认情况,其中 dynamic=False
。在这里,所有的预测都是超前一步的预测。由于我将 endog
的每个元素都设置为 1,并且我们有一个参数为 0.5 的 AR(1) 模型,因此所有向前一步的预测都将等于 0.5 * 1 = 0.5。
在第二列 (d=0) 中,我们指定 dynamic=0
以便动态预测从第一个预测开始。这意味着我们不会使用 start - 1
之后的任何 endog
数据来形成我们的预测,在这种情况下,这意味着我们不会使用 2018 年 12 月 31 日之后的任何数据来进行预测。第一个预测将等于 2018 年 12 月 31 日观测值的 0.5 倍,即 0.5 * 1 = 0.5。每个后续预测将等于 0.5 * 前一个预测,因此第二个预测为 0.5 * 0.5 = 0.25,依此类推
第三列 (d=1) 与第二列类似,只是此处 dynamic=1
以便动态预测从第二个预测开始。这意味着我们不使用 start
之后的任何 endog
数据(即 2019 年 1 月 1 日之后)。
我正在尝试了解如何使用 statsmodels
.
我的理解是 results.get_prediction(start=, dynamic=)
api 执行此操作,但我无法理解它是如何工作的。我的训练数据由 15T 频率的本地化 DateTimeIndex (tz='Sydney\Australia') 索引。我想预测“2019-02-04 00:00:00+1100”的一整天,使用前一步预测到“2019-02-04 06:00:00+1100”之前预测的内生值剩下的时间。
下面的代码是否正确?似乎 statsmodel 将开始转换为时间戳并将动态视为频率的倍数,因此这应该使用提前 1 步开始模拟,直到 06:00 然后使用先前预测的内生值。结果看起来不太好,所以我想确认这是一个模型问题,而不是我的诊断不正确。
dt = '2019-02-04'
predict = res.get_prediction(start='2019-02-04 00:00:00+11:00')
predict_dy = res.get_prediction(start='2019-02-04 00:00:00+11:00', dynamic=4*6)
fig = plt.figure(figsize=(10,10)) ax = fig.gca()
y_train[dt].plot(ax=ax, style='o', label='Observed')
predict.predicted_mean[dt].plot(ax=ax, style='r--', label='One-step-ahead forecast')
predict_dy.predicted_mean[dt].plot(ax=ax, style='g', label='Dynamic forecast')
It seems statsmodel converts the start to a TimeStamp
是的,如果您给它一个字符串值,那么它会尝试将其映射到数据集中的索引(如时间戳)。
and treats dynamic as a multiple of the freq
但这是不正确的。 dynamic
是 start
的整数偏移量。因此,如果 dynamic=0
,则意味着动态预测从 start
开始,而如果 dynamic=1
,则意味着动态预测从 start+1
.
我不太清楚你的示例中发生了什么(或者你认为你生成的预测不太好),所以这里描述了 dynamic
的工作原理,可能会有所帮助:
这是一个可能有助于解释事物运作方式的示例。本练习的几个关键点是:
- 我设置
endog
的所有元素都等于1 - 这是一个参数为 0.5 的 AR(1) 模型。这意味着如果我们知道 y_t,那么 y_t+1 的预测等于 0.5 * y_t.
现在,示例代码是:
ix = pd.date_range(start='2018-12-01', end='2019-01-31', freq='D')
endog = pd.Series(np.ones(len(ix)), index=ix)
mod = sm.tsa.SARIMAX(endog, order=(1, 0, 0), concentrate_scale=True)
res = mod.smooth([0.5])
p1 = res.predict(start='January 1, 2019', end='January 5, 2019').rename('d=False')
p2 = res.predict(start='January 1, 2019', end='January 5, 2019', dynamic=0).rename('d=0')
p3 = res.predict(start='January 1, 2019', end='January 5, 2019', dynamic=1).rename('d=2')
print(pd.concat([p1, p2, p3], axis=1))
这给出:
d=False d=0 d=2
2019-01-01 0.5 0.50000 0.5000
2019-01-02 0.5 0.25000 0.5000
2019-01-03 0.5 0.12500 0.2500
2019-01-04 0.5 0.06250 0.1250
2019-01-05 0.5 0.03125 0.0625
第一列 (d=False) 是默认情况,其中 dynamic=False
。在这里,所有的预测都是超前一步的预测。由于我将 endog
的每个元素都设置为 1,并且我们有一个参数为 0.5 的 AR(1) 模型,因此所有向前一步的预测都将等于 0.5 * 1 = 0.5。
在第二列 (d=0) 中,我们指定 dynamic=0
以便动态预测从第一个预测开始。这意味着我们不会使用 start - 1
之后的任何 endog
数据来形成我们的预测,在这种情况下,这意味着我们不会使用 2018 年 12 月 31 日之后的任何数据来进行预测。第一个预测将等于 2018 年 12 月 31 日观测值的 0.5 倍,即 0.5 * 1 = 0.5。每个后续预测将等于 0.5 * 前一个预测,因此第二个预测为 0.5 * 0.5 = 0.25,依此类推
第三列 (d=1) 与第二列类似,只是此处 dynamic=1
以便动态预测从第二个预测开始。这意味着我们不使用 start
之后的任何 endog
数据(即 2019 年 1 月 1 日之后)。