我用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”中找不到任何与此相关的函数。我该怎么做?
从 GitHub 问题的 this 答案中,很明显,您应该使用新的
ETSModel
类,而不是旧的(但仍然存在以实现兼容性)ExponentialSmoothing
。
ETSModel
比 ExponentialSmoothing
包含更多参数和更多功能。
要计算置信区间,我建议您使用
simulate
的ETSResults
方法:
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(在本例中,训练数据集中的项目数 y
相同)。
然后,使用 DataFrame quantile
方法计算置信区间(记住 axis='columns'
选项)。
您还可以从 df_simul
计算其他统计数据。
我还检查了源代码:
simulate
是由forecast
方法内部调用的,用于预测未来的步骤。因此,您还可以使用相同的方法预测未来的步骤及其置信区间:只需使用 anchor='end'
,以便模拟将从 y
中的最后一步开始。
公平地说,还有一种更直接的方法来计算置信区间:
get_prediction
方法(内部使用simulate
)。但我不太喜欢它的界面,它对我来说不够灵活,我没有找到一种方法来指定所需的置信区间。在我看来,使用 simulate
方法的方法非常容易理解,而且非常灵活。
如果您想了解有关如何执行此类模拟的更多详细信息,请阅读优秀的预测:原理与实践在线书籍中的此章节。
补充@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
实现的答案(我自己)......@Enrico,我们可以通过以下方式使用get_prediction:
from statsmodels.tsa.exponential_smoothing.ets import ETSModel
#---sales:pd.series, time series data(index should be timedate format)
#---new advanced holt's winter ts model implementation
HWTES_Model = ETSModel(endog=sales, trend= 'mul', seasonal='mul', seasonal_periods=4).fit()
point_forecast = HWTES_Model.forecast(16)
#-------Confidence Interval forecast calculation start------------------
ci = HWTES_Model.get_prediction(start = point_forecast.index[0],
end = point_forecast.index[-1])
lower_conf_forecast = ci.pred_int(alpha=alpha_1).iloc[:,0]
upper_conf_forecast = ci.pred_int(alpha=alpha_1).iloc[:,1]
#-------Confidence Interval forecast calculation end-----------------
为了补充之前的答案,我提供了在预测之上绘制 CI 的函数。
def ets_forecast(model, h=8):
# Simulate predictions.
n_steps_prediction =h
n_repetitions = 1000
yhat = model.forecast(h)
df_simul = model.simulate(
nsimulations=n_steps_prediction,
repetitions=n_repetitions,
anchor='end',
)
# Calculate confidence intervals.
upper_ci = df_simul.quantile(q=0.975, axis='columns')
lower_ci = df_simul.quantile(q=0.025, axis='columns')
plt.plot(yhat.index, yhat.values)
plt.fill_between(yhat.index, (lower_ci), (upper_ci), color='blue', alpha=0.1)
return yhat
plt.plot(y)
ets_forecast(model2, h=8)
plt.show()
在下面的代码中我将展示:
get_prediction.summary_frame
从新模型ETSModel
获得预测和置信区间simulate.forecast
仅获得没有置信区间的预测ExponentialSmoothing
用法,返回的数据与ETSModel
我用的三个中
get_prediction.summary_frame
,这是最完整的一个。
# see https://www.statsmodels.org/dev/examples/notebooks/generated/ets.html#Holt-Winters'-seasonal-method
# ETS source code see https://www.statsmodels.org/dev/_modules/statsmodels/tsa/exponential_smoothing/ets.html
# see https://otexts.com/fpp3/ets-forecasting.html (8.4, 8.5, 8.6)
# for the ETS model to work with seasonal_period of 12, we need at least 24 data points
import pandas as pd
from statsmodels.tsa.exponential_smoothing.ets import ETSModel
from statsmodels.tsa.holtwinters import ExponentialSmoothing
import numpy as np
# Sample data provided
data = {
"Month": list(range(1, 25)),
"Sales": [8.9, 8.1, 6.95, 9, 10.1, 11.2, 12.8, 9, 10.1, 10.2, 10.99, 13, 10, 9, 8, 10, 11, 12, 14, 10, 11, 11, 12, 14]
}
# Create a DataFrame
df_data = pd.DataFrame(data)
# Convert the 'Month' column to a datetime format
df_data.set_index('Month', inplace=True)
df_data.index = pd.date_range(start='1/1/2020', periods=len(df_data), freq='M')
# Interpolate missing data (if any)
df_data['Sales'] = df_data['Sales'].interpolate()
#
# <new AAA model (ETSModel) with confidence>
#
# Fit the AAA model
# Build model
ets_model = ETSModel(
endog=df_data['Sales'],
error="add",
trend='add',
seasonal='add',
seasonal_periods=12,
)
ets_result = ets_model.fit(disp=False) # Set disp=False to disable optimization messages
#
# Get prediction with `get_prediction`
#
# see https://www.statsmodels.org/devel/generated/statsmodels.tsa.exponential_smoothing.ets.ETSResults.get_prediction.html
# source code https://www.statsmodels.org/devel/_modules/statsmodels/tsa/exponential_smoothing/ets.html#ETSResults.get_prediction
pred = ets_result.get_prediction(start = 24, end = 24+11)
#pred = ets_result.get_prediction(start = df_simul.index[0], end = df_simul.index[-1]) # works also with dates
print("\nnForecast for the next 12 months+ + 95% Confidence Intervals with `ETSModel` & `get_prediction` & `summary_frame`:")
df_pred = pred.summary_frame(alpha=0.05)
print(df_pred)
#
# ALTERNATIVE METHOD TO `get_prediction`, TO GET ONLY THE FORECAST COLUMN WITHOUT CONFIDENCE INTERVAL
# Get predictions with `simulate`
#
# see https://www.statsmodels.org/dev/generated/statsmodels.tsa.exponential_smoothing.ets.ETSResults.simulate.html
# source code https://www.statsmodels.org/dev/_modules/statsmodels/tsa/exponential_smoothing/ets.html#ETSResults.simulate
df_simul = ets_result.simulate(
nsimulations=12, # forecast the next 12 months
repetitions=1000,
anchor='end',
)
print("\nForecast for the next 12 months with `ETSModel` & `simulate`:")
print(ets_result.forecast(steps=12))
# Calculate and print confidence intervals with `quantile` (not needed)
#
# </new AAA model (ETSModel) with confidence>
#
#
# <old AAA model (ExponentialSmoothing)>
#
# Fit the AAA model
model = ExponentialSmoothing(
df_data['Sales'],
trend='add',
seasonal='add',
seasonal_periods=12
)
fit_model = model.fit()
# Forecast the next 12 months
forecast = fit_model.forecast(12)
forecast.index = range(1, 13)
# Print the forecast and confidence intervals
print("\nForecast for the next 12 months with `ExponentialSmoothing` (old model):")
print(forecast)
#
# </old AAA model (ExponentialSmoothing)>
#