# es() - Exponential Smoothing
Author: Ivan Svetunkov
Date: 2024-06-19

#### Ivan Svetunkov

#### 2024-06-19

`es()` is a part of smooth package and is a wrapper for the ADAM function with `distribution="dnorm"`. It implements Exponential Smoothing in the ETS form, selecting the most appropriate model among 30 possible ones.

We will use some of the functions of the `greybox` package in this vignette for demonstrational purposes.

Let’s load the necessary packages:

    require(smooth)
    require(greybox)

The simplest call for the `es()` function is:

    ourModel <- es(BJsales, h=12, holdout=TRUE, silent=FALSE)

    ## Forming the pool of models based on... ANN , AAN , Estimation progress:    33 %44 %56 %67 %78 %89 %100 %... Done!

    ourModel

    ## Time elapsed: 0.21 seconds
    ## Model estimated using es() function: ETS(AAdN)
    ## Distribution assumed in the model: Normal
    ## Loss function type: likelihood; Loss function value: 237.6516
    ## Persistence vector g:
    ##  alpha   beta
    ## 0.9156 0.3339
    ## Damping parameter: 0.8587
    ## Sample size: 138
    ## Number of estimated parameters: 6
    ## Number of degrees of freedom: 132
    ## Information criteria:
    ##      AIC     AICc      BIC     BICc
    ## 487.3032 487.9444 504.8667 506.4464
    ##
    ## Forecast errors:
    ## ME: 2.794; MAE: 2.948; RMSE: 3.629
    ## sCE: 14.75%; Asymmetry: 87.7%; sMAE: 1.297%; sMSE: 0.025%
    ## MASE: 2.475; RMSSE: 2.365; rMAE: 0.951; rRMSE: 0.947

In this case function uses branch and bound algorithm to form a pool of models to check and after that constructs a model with the lowest information criterion. As we can see, it also produces an output with brief information about the model, which contains:

1. How much time was elapsed for the model construction;
2. What type of ETS was selected;
3. Values of persistence vector (smoothing parameters);
4. What type of initialisation was used;
5. How many parameters were estimated (standard deviation is included);
6. Cost function type and the value of that cost function;
7. Information criteria for this model;
8. Forecast errors (because we have set `holdout=TRUE`).

The function has also produced a graph with actual values, fitted values and point forecasts.

If we need prediction interval, then we can use the `forecast()` method:

    plot(forecast(ourModel, h=12, interval="prediction"))

The same model can be reused for different purposes, for example to produce forecasts based on newly available data:

    es(BJsales, model=ourModel, h=12, holdout=FALSE)

    ## Time elapsed: 0 seconds
    ## Model estimated using es() function: ETS(AAdN)
    ## Distribution assumed in the model: Normal
    ## Loss function type: likelihood; Loss function value: 255.4135
    ## Persistence vector g:
    ##  alpha   beta
    ## 0.9156 0.3339
    ## Damping parameter: 0.8587
    ## Sample size: 150
    ## Number of estimated parameters: 1
    ## Number of degrees of freedom: 149
    ## Information criteria:
    ##      AIC     AICc      BIC     BICc
    ## 512.8269 512.8539 515.8376 515.9053

We can also extract the type of model in order to reuse it later:

    modelType(ourModel)

    ## [1] "AAdN"

This handy function also works with `ets()` from forecast package.

If we need actual values from the model, we can use `actuals()` method from `greybox` package:

    actuals(ourModel)

    ## Time Series:
    ## Start = 1
    ## End = 138
    ## Frequency = 1
    ##   [1] 200.1 199.5 199.4 198.9 199.0 200.2 198.6 200.0 200.3 201.2 201.6 201.5
    ##  [13] 201.5 203.5 204.9 207.1 210.5 210.5 209.8 208.8 209.5 213.2 213.7 215.1
    ##  [25] 218.7 219.8 220.5 223.8 222.8 223.8 221.7 222.3 220.8 219.4 220.1 220.6
    ##  [37] 218.9 217.8 217.7 215.0 215.3 215.9 216.7 216.7 217.7 218.7 222.9 224.9
    ##  [49] 222.2 220.7 220.0 218.7 217.0 215.9 215.8 214.1 212.3 213.9 214.6 213.6
    ##  [61] 212.1 211.4 213.1 212.9 213.3 211.5 212.3 213.0 211.0 210.7 210.1 211.4
    ##  [73] 210.0 209.7 208.8 208.8 208.8 210.6 211.9 212.8 212.5 214.8 215.3 217.5
    ##  [85] 218.8 220.7 222.2 226.7 228.4 233.2 235.7 237.1 240.6 243.8 245.3 246.0
    ##  [97] 246.3 247.7 247.6 247.8 249.4 249.0 249.9 250.5 251.5 249.0 247.6 248.8
    ## [109] 250.4 250.7 253.0 253.7 255.0 256.2 256.0 257.4 260.4 260.0 261.3 260.4
    ## [121] 261.6 260.8 259.8 259.0 258.9 257.4 257.7 257.9 257.4 257.3 257.6 258.9
    ## [133] 257.8 257.7 257.2 257.5 256.8 257.5

We can also use persistence or initials only from the model to construct the other one:

    # Provided initials
    es(BJsales, model=modelType(ourModel),
       h=12, holdout=FALSE,
       initial=ourModel$initial)

    ## Time elapsed: 0.01 seconds
    ## Model estimated using es() function: ETS(AAdN)
    ## Distribution assumed in the model: Normal
    ## Loss function type: likelihood; Loss function value: 255.3054
    ## Persistence vector g:
    ##  alpha   beta
    ## 0.9645 0.2960
    ## Damping parameter: 0.8739
    ## Sample size: 150
    ## Number of estimated parameters: 4
    ## Number of degrees of freedom: 146
    ## Information criteria:
    ##      AIC     AICc      BIC     BICc
    ## 518.6108 518.8867 530.6534 531.3445

    # Provided persistence
    es(BJsales, model=modelType(ourModel),
       h=12, holdout=FALSE,
       persistence=ourModel$persistence)

    ## Time elapsed: 0.02 seconds
    ## Model estimated using es() function: ETS(AAdN)
    ## Distribution assumed in the model: Normal
    ## Loss function type: likelihood; Loss function value: 255.4113
    ## Persistence vector g:
    ##  alpha   beta
    ## 0.9156 0.3339
    ## Damping parameter: 0.8566
    ## Sample size: 150
    ## Number of estimated parameters: 4
    ## Number of degrees of freedom: 146
    ## Information criteria:
    ##      AIC     AICc      BIC     BICc
    ## 518.8226 519.0985 530.8651 531.5563

or provide some arbitrary values:

    es(BJsales, model=modelType(ourModel),
       h=12, holdout=FALSE,
       initial=200)

    ## Time elapsed: 0.02 seconds
    ## Model estimated using es() function: ETS(AAdN)
    ## Distribution assumed in the model: Normal
    ## Loss function type: likelihood; Loss function value: 255.3549
    ## Persistence vector g:
    ##  alpha   beta
    ## 0.9735 0.2897
    ## Damping parameter: 0.8755
    ## Sample size: 150
    ## Number of estimated parameters: 5
    ## Number of degrees of freedom: 145
    ## Information criteria:
    ##      AIC     AICc      BIC     BICc
    ## 520.7097 521.1264 535.7629 536.8068

Using some other parameters may lead to completely different model and forecasts (see discussion of the additional parameters in the online textbook about ADAM):

    es(BJsales, h=12, holdout=TRUE, loss="MSEh", bounds="a", ic="BIC")

    ## Time elapsed: 0.83 seconds
    ## Model estimated using es() function: ETS(AAN)
    ## Distribution assumed in the model: Normal
    ## Loss function type: MSEh; Loss function value: 88.75
    ## Persistence vector g:
    ##  alpha   beta
    ## 1.5468 0.0000
    ##
    ## Sample size: 138
    ## Number of estimated parameters: 4
    ## Number of degrees of freedom: 134
    ## Information criteria:
    ##      AIC     AICc      BIC     BICc
    ## 1018.671 1018.971 1030.380 1031.121
    ##
    ## Forecast errors:
    ## ME: -0.521; MAE: 1.234; RMSE: 1.377
    ## sCE: -2.75%; Asymmetry: -47.1%; sMAE: 0.543%; sMSE: 0.004%
    ## MASE: 1.036; RMSSE: 0.898; rMAE: 0.398; rRMSE: 0.359

You can play around with all the available parameters to see what’s their effect on the final model.

In order to combine forecasts we need to use “C” letter:

    es(BJsales, model="CCN", h=12, holdout=TRUE)

    ## Time elapsed: 0.23 seconds
    ## Model estimated: ETS(CCN)
    ## Loss function type: likelihood
    ##
    ## Number of models combined: 10
    ## Sample size: 138
    ## Average number of estimated parameters: 6.3012
    ## Average number of degrees of freedom: 131.6988
    ##
    ## Forecast errors:
    ## ME: 2.813; MAE: 2.968; RMSE: 3.654
    ## sCE: 14.851%; sMAE: 1.306%; sMSE: 0.026%
    ## MASE: 2.492; RMSSE: 2.382; rMAE: 0.957; rRMSE: 0.954

Model selection from a specified pool and forecasts combination are called using respectively:

    # Select the best model in the pool
    es(BJsales, model=c("ANN","AAN","AAdN","MNN","MAN","MAdN"),
       h=12, holdout=TRUE)

    ## Time elapsed: 0.11 seconds
    ## Model estimated using es() function: ETS(AAdN)
    ## Distribution assumed in the model: Normal
    ## Loss function type: likelihood; Loss function value: 237.6516
    ## Persistence vector g:
    ##  alpha   beta
    ## 0.9156 0.3339
    ## Damping parameter: 0.8587
    ## Sample size: 138
    ## Number of estimated parameters: 6
    ## Number of degrees of freedom: 132
    ## Information criteria:
    ##      AIC     AICc      BIC     BICc
    ## 487.3032 487.9444 504.8667 506.4464
    ##
    ## Forecast errors:
    ## ME: 2.794; MAE: 2.948; RMSE: 3.629
    ## sCE: 14.75%; Asymmetry: 87.7%; sMAE: 1.297%; sMSE: 0.025%
    ## MASE: 2.475; RMSSE: 2.365; rMAE: 0.951; rRMSE: 0.947

    # Combine the pool of models
    es(BJsales, model=c("CCC","ANN","AAN","AAdN","MNN","MAN","MAdN"),
       h=12, holdout=TRUE)

    ## Time elapsed: 0.11 seconds
    ## Model estimated: ETS(CCN)
    ## Loss function type: likelihood
    ##
    ## Number of models combined: 6
    ## Sample size: 138
    ## Average number of estimated parameters: 6.5053
    ## Average number of degrees of freedom: 131.4947
    ##
    ## Forecast errors:
    ## ME: 2.817; MAE: 2.968; RMSE: 3.654
    ## sCE: 14.872%; sMAE: 1.305%; sMSE: 0.026%
    ## MASE: 2.491; RMSSE: 2.382; rMAE: 0.957; rRMSE: 0.954

Now we introduce explanatory variable in ETS:

    x <- BJsales.lead

and fit an ETSX model with the exogenous variable first:

    es(BJsales, model="ZZZ", h=12, holdout=TRUE,
       xreg=x)

    ## Time elapsed: 0.73 seconds
    ## Model estimated using es() function: ETSX(AMdN)
    ## Distribution assumed in the model: Normal
    ## Loss function type: likelihood; Loss function value: 237.4933
    ## Persistence vector g (excluding xreg):
    ##  alpha   beta
    ## 0.9494 0.2913
    ## Damping parameter: 0.8762
    ## Sample size: 138
    ## Number of estimated parameters: 7
    ## Number of degrees of freedom: 131
    ## Information criteria:
    ##      AIC     AICc      BIC     BICc
    ## 488.9866 489.8482 509.4774 511.5999
    ##
    ## Forecast errors:
    ## ME: 2.875; MAE: 2.999; RMSE: 3.701
    ## sCE: 15.176%; Asymmetry: 89.9%; sMAE: 1.319%; sMSE: 0.027%
    ## MASE: 2.517; RMSSE: 2.412; rMAE: 0.967; rRMSE: 0.966

If we want to check if lagged x can be used for forecasting purposes, we can use `xregExpander()` function from `greybox` package:

    es(BJsales, model="ZZZ", h=12, holdout=TRUE,
       xreg=xregExpander(x), regressors="use")

    ## Time elapsed: 1.54 seconds
    ## Model estimated using es() function: ETSX(AMdN)
    ## Distribution assumed in the model: Normal
    ## Loss function type: likelihood; Loss function value: 236.4443
    ## Persistence vector g (excluding xreg):
    ##  alpha   beta
    ## 0.9881 0.3253
    ## Damping parameter: 0.8288
    ## Sample size: 138
    ## Number of estimated parameters: 9
    ## Number of degrees of freedom: 129
    ## Information criteria:
    ##      AIC     AICc      BIC     BICc
    ## 490.8886 492.2949 517.2339 520.6984
    ##
    ## Forecast errors:
    ## ME: 2.352; MAE: 2.849; RMSE: 3.349
    ## sCE: 12.417%; Asymmetry: 72.6%; sMAE: 1.253%; sMSE: 0.022%
    ## MASE: 2.391; RMSSE: 2.183; rMAE: 0.919; rRMSE: 0.874

We can also construct a model with selected exogenous (based on IC):

    es(BJsales, model="ZZZ", h=12, holdout=TRUE,
       xreg=xregExpander(x), regressors="select")

    ## Time elapsed: 0.99 seconds
    ## Model estimated using es() function: ETS(AAdN)
    ## Distribution assumed in the model: Normal
    ## Loss function type: likelihood; Loss function value: 237.6516
    ## Persistence vector g:
    ##  alpha   beta
    ## 0.9156 0.3339
    ## Damping parameter: 0.8587
    ## Sample size: 138
    ## Number of estimated parameters: 6
    ## Number of degrees of freedom: 132
    ## Information criteria:
    ##      AIC     AICc      BIC     BICc
    ## 487.3032 487.9444 504.8667 506.4464
    ##
    ## Forecast errors:
    ## ME: 2.794; MAE: 2.948; RMSE: 3.629
    ## sCE: 14.75%; Asymmetry: 87.7%; sMAE: 1.297%; sMSE: 0.025%
    ## MASE: 2.475; RMSSE: 2.365; rMAE: 0.951; rRMSE: 0.947

Finally, if you work with M or M3 data, and need to test a function on a specific time series, you can use the following simplified call:

    es(Mcomp::M3$N2457, silent=FALSE)

This command has taken the data, split it into in-sample and holdout and produced the forecast of appropriate length to the holdout.