I am using statsmodels.tsa.holtwinters ExponentialSmoothing to fit the model to a time series. I am performing grid search for parameters of trend, seasonal, and damped_trend. The rest of the parameters are estimated by the model. Because I noticed some odd behavior (as described here), I then re-use the same set of grid-search and estimated parameters to initialize the model for the same data and print the first and second set of fitted values. This second set of forecasted values is nearly identical to the first set for all 8 combinations of grid-search parameters, except one, where it does not look anything like the initial fit. I would like to understand why this is happening?
The model and its output are specified as below:
model = ExponentialSmoothing(
df_train['y'],
trend=config['trend'],
seasonal=config['seasonal'],
damped_trend=config['damped_trend'],
initialization_method='estimated'
).fit()
print("Model parameters: ", config,'\n',model.params)
#creating output dataset
proj_act = pd.DataFrame(model.fittedvalues, columns=["HWES"])
proj_forecast = pd.DataFrame(model.forecast(steps=val_period), columns=["HWES"])
proj = pd.concat([proj_act, proj_forecast])
df = df.reset_index().merge(proj.reset_index().rename(columns={"index":"ds"}), how="outer", on="ds")
The re-initialization looks like this:
model2 = ExponentialSmoothing(
df_train['y'],
trend=config['trend'],
seasonal=config['seasonal'],
damped_trend=config['damped_trend'],
initialization_method='known',
use_boxcox=model.params.get('use_boxcox'),
initial_level=model.params.get('initial_level'),
initial_trend=model.params.get('initial_trend'),
initial_seasonal=model.params.get('initial_seasons')
).fit(
smoothing_level=model.params.get('smoothing_level'),
smoothing_trend=model.params.get('smoothing_trend'),
smoothing_seasonal=model.params.get('smoothing_seasonal'),
damping_trend = model.params.get('damping_trend'),
remove_bias = model.params.get('remove_bias')
)
#adding to the output dataset and printing
proj_act2 = pd.DataFrame(model2.fittedvalues, columns=["HWES"])
proj_forecast2 = pd.DataFrame(model2.forecast(steps=val_period), columns=["HWES"])
proj2 = pd.concat([proj_act2, proj_forecast2])
print(df.reset_index().merge(proj2.reset_index().rename(columns={"index":"ds"}), how="outer", on="ds"))
The discrepancy in the two forecasts occurs at this parameter setting:
Printing model parameters:
Model parameters:
{'damped_trend': False,
'seasonal': 'Add',
'trend': 'Mul'}
{'smoothing_level': 0.1817857142857143,
'smoothing_trend': 9.999999999999999e-05,
'smoothing_seasonal': 0.12587912087912087,
'damping_trend': nan,
'initial_level': 4670610.211111108,
'initial_trend': 1.0019498382292253,
'initial_seasons': array([ -55119.00260417, -14312.9921875 , 164648.39322917,
-143115.60677083, 137116.09114583, -54149.2734375 ,
57126.3828125 , 26319.55989583, -300643.45052083,
131789.84114583, -75055.81510417, 125395.87239583]),
'use_boxcox': False,
'lamda': None,
'remove_bias': False}
Printing intialization parameters: {'Ini_trend': 1.0019498382292253, 'Ini_season': array([ -55119.00260417, -14312.9921875 , 164648.39322917, -143115.60677083, 137116.09114583, -54149.2734375 , 57126.3828125 , 26319.55989583, -300643.45052083, 131789.84114583, -75055.81510417, 125395.87239583]), 'Ini_level': 4670610.211111108, 'Trend': 'Mul', 'Seasonality': 'Add', 'Damped': False, 'Alpha': 0.1817857142857143, 'Beta': 9.999999999999999e-05, 'Gamma': 0.12587912087912087, 'Phi': nan, 'Error_Percent_Weighted_Mean_Val': 1.8787153394783243, 'BIC': 2365.7625492513066}