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

问题描述 投票:0回答:5

我用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”中找不到任何与此相关的函数。我该怎么做?

python statsmodels forecasting confidence-interval holtwinters
5个回答
3
投票

从 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
方法的方法非常容易理解,而且非常灵活。

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


0
投票

补充@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

0
投票

实现的答案(我自己)......@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-----------------

0
投票

为了补充之前的答案,我提供了在预测之上绘制 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()

enter image description here


0
投票

在下面的代码中我将展示:

我用的三个中

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)>
#
© www.soinside.com 2019 - 2024. All rights reserved.