如何在 python 中获取 statsmodels.tsa.holtwinters-ExponentialSmoothing 模型的置信区间?

How to take confidence interval of statsmodels.tsa.holtwinters-ExponentialSmoothing Models in python?

我在 python 中使用 ExponentialSmoothing 进行了时间序列预测分析。我用了 statsmodels.tsa.holtwinters.

model = ExponentialSmoothing(df, seasonal='mul', seasonal_periods=12).fit()
pred = model.predict(start=df.index[0], end=122)

plt.plot(df_fc.index, df_fc, label='Train')
plt.plot(pred.index, pred, label='Holt-Winters')
plt.legend(loc='best')

我想获取模型结果的置信区间。但是我在“statsmodels.tsa.holtwinters - ExponentialSmoothing”中找不到任何关于此的功能。我该怎么做?

来自 this 对 GitHub 问题的回答,很明显你应该使用新的 ETSModel class,而不是旧的(但仍然存在为了兼容性)ExponentialSmoothingETSModel 包含比 ExponentialSmoothing 更多的参数和更多的功能。

计算置信区间,建议使用ETSResultssimulate方法:

from statsmodels.tsa.exponential_smoothing.ets import ETSModel
import pandas as pd


# Build model.
ets_model = ETSModel(
    endog=y, # y should be a pd.Series
    seasonal='mul',
    seasonal_periods=12,
)
ets_result = ets_model.fit()

# Simulate predictions.
n_steps_prediction = y.shape[0]
n_repetitions = 500

df_simul = ets_result.simulate(
    nsimulations=n_steps_prediction,
    repetitions=n_repetitions,
    anchor='start',
)

# Calculate confidence intervals.
upper_ci = df_simul.quantile(q=0.9, axis='columns')
lower_ci = df_simul.quantile(q=0.1, axis='columns')

基本上,调用 simulate 方法你会得到一个包含 n_repetitions 列和 n_steps_prediction 步骤的 DataFrame(在这种情况下,与你训练中相同数量的项目 data-set y)。 然后,您使用 DataFrame quantile 方法计算置信区间(记住 axis='columns' 选项)。 您还可以从 df_simul.

计算其他统计数据

我也查了下源码:simulateforecast方法内部调用的,用来预测未来的步数。因此,您还可以使用相同的方法预测未来的步骤及其置信区间:只需使用 anchor='end',这样模拟将从 y.

的最后一步开始

公平地说,还有一种更直接的方法来计算置信区间:get_prediction 方法(内部使用 simulate)。但我不太喜欢它的界面,它对我来说不够灵活,我没有找到指定所需置信区间的方法。在我看来,使用 simulate 方法的方法非常容易理解,而且非常灵活。

如果您想了解有关如何执行此类模拟的更多详细信息,请阅读优秀的 预测:原理与实践 在线书籍中的 this 章节。

补充@Enrico 的回答,我们可以按以下方式使用 get_prediction

ci = model.get_prediction(start =  forecast_data.index[0], end = forecast_data.index[-1])
preds = ci.pred_int(alpha = .05) #confidence interval
limits = ci.predicted_mean

preds = pd.concat([limits, preds], axis = 1)
preds.columns = ['yhat', 'yhat_lower', 'yhat_upper']
preds