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}

Output: A dataframe with the original forecast in HW_x column and the re-initialized model forecast in HW_y column. The error column is the % difference of the original forecast from the actuals.

0

There are 0 answers