Type at least 2 letters. Enter opens the first result, Esc closes.

    Time Series and Forecasting · Lesson 4 · First forecasts and honest evaluation

    Exponential smoothing: from simple smoothing to Holt-Winters and ETS

    Intermediate 75 min 4 interactive figures 5 videos Colab notebook

    Before this lesson: lesson 01 (level, trend, seasonal period mm, additive and multiplicative seasons) and lesson 03 (benchmarks, rolling origin, MASE). One-dimensional minimisation helps (optimization lesson 01). Time: about 75 minutes, plus the notebook.


    Why this matters #

    • It is used everywhere in operations. Inventory systems, demand planning and capacity planning have used exponential smoothing since the 1950s (Brown, Holt, Winters). Spreadsheet software has it built in: Excel's FORECAST.ETS uses an additive ETS model.
    • It is a strong benchmark. In the M4 competition, the benchmark "Comb", the average of SES, Holt and damped trend forecasts, was more accurate than all six pure machine-learning methods (Makridakis et al. 2020). The Theta method, the winner of the M3 competition, is equivalent to SES with drift (Hyndman and Billah 2003).
    • It is the simplest state-space model. Its update "state = prediction + gain × error" is the same structure as the Kalman filter (lesson 07), and SES is a special case of ARIMA (lesson 06). Recurrent neural networks (lesson 09) also carry a state forward and update it with each new value; the ES-RNN hybrid that won M4 combined Holt-Winters equations with an LSTM (Smyl 2020).
    • Libraries: statsmodels (ExponentialSmoothing, ETSModel), statsforecast (AutoETS), R fable (ETS()) and forecast (ets()).

    1. Predict first #

    2. The picture #

    An average with fading weights #

    Take the last observed values yt,yt−1,yt−2,…y_t, y_{t-1}, y_{t-2}, \dots. The SES forecast of the next value is

    y^t+1∣t=αyt+α(1−α)yt−1+α(1−α)2yt−2+…\hat y_{t+1\mid t} = \alpha y_t + \alpha(1-\alpha) y_{t-1} + \alpha(1-\alpha)^2 y_{t-2} + \dots

    with 0<α≤10 < \alpha \le 1. The weights α,α(1−α),α(1−α)2,…\alpha, \alpha(1-\alpha), \alpha(1-\alpha)^2, \dots shrink by the factor 1−α1 - \alpha at each step back: they decay exponentially, hence the name. With α=0.2\alpha = 0.2 the weights are 0.2,0.16,0.128,…0.2, 0.16, 0.128, \dots: many past values matter. With α=0.8\alpha = 0.8 they are 0.8,0.16,0.032,…0.8, 0.16, 0.032, \dots: almost only the newest value matters.

    Interactive figure: loading…

    Move α\alpha. The bars are the weights α(1−α)j\alpha(1-\alpha)^j of the last 20 observations; the yellow bar is the newest one. Above, the level (aqua) smooths the data (blue), and the forecast (orange) is a flat line from the origin. Small α\alpha: long memory and a smooth level. α=1\alpha = 1: the level is the last value, and SES becomes the naive forecast.

    State plus gain times error #

    The same forecast can be computed with one number in memory, the level ℓt\ell_t. When the new value yty_t arrives:

    1. the forecast was y^t∣t−1=ℓt−1\hat y_{t\mid t-1} = \ell_{t-1};
    2. the error is et=yt−ℓt−1e_t = y_t - \ell_{t-1};
    3. move the level a fraction α\alpha of the way: ℓt=ℓt−1+αet\ell_t = \ell_{t-1} + \alpha e_t.

    If the forecast was too low (et>0e_t > 0), the level goes up; if it was right, nothing changes. Holt's and Winters' methods keep more states (a trend btb_t and seasonal states sts_t) and update each of them with its own gain times the same error. Section 3.5 shows these updates step by step.

    Quick check

    SES with α=0.5\alpha = 0.5. What weight does the forecast y^t+1∣t\hat y_{t+1\mid t} give to yt−3y_{t-3}?

    3. Definitions and main results #

    3.1 Simple exponential smoothing: three equal forms #

    Definition (SES). Choose 0<α≤10 < \alpha \le 1 and a starting level ℓ0\ell_0. For t=1,2,…,nt = 1, 2, \dots, n:

    forecast y^t+h∣t=ℓt (h=1,2,… ),level ℓt=αyt+(1−α) ℓt−1.\text{forecast } \hat y_{t+h\mid t} = \ell_t \ (h = 1, 2, \dots), \qquad \text{level } \ell_t = \alpha y_t + (1 - \alpha)\,\ell_{t-1}.

    This is the component form. The forecast is flat: the same value ℓn\ell_n for every horizon, because SES has no trend and no season.

    Theorem (three equal forms). For every t≥1t \ge 1:

    1. error-correction form: ℓt=ℓt−1+αet\ell_t = \ell_{t-1} + \alpha e_t with et=yt−ℓt−1e_t = y_t - \ell_{t-1};
    2. weighted-average form: ℓt=∑j=0t−1α(1−α)jyt−j+(1−α)tℓ0\ell_t = \sum_{j=0}^{t-1} \alpha(1-\alpha)^j y_{t-j} + (1-\alpha)^t \ell_0, and the weights sum to 1.

    Proof.

    1. αyt+(1−α)ℓt−1=ℓt−1+α(yt−ℓt−1)=ℓt−1+αet\alpha y_t + (1-\alpha)\ell_{t-1} = \ell_{t-1} + \alpha(y_t - \ell_{t-1}) = \ell_{t-1} + \alpha e_t.
    2. By induction on tt. For t=1t = 1: ℓ1=αy1+(1−α)ℓ0\ell_1 = \alpha y_1 + (1-\alpha)\ell_0, which is the formula. If the formula holds for t−1t - 1, then ℓt=αyt+(1−α)[∑j=0t−2α(1−α)jyt−1−j+(1−α)t−1ℓ0]\ell_t = \alpha y_t + (1-\alpha)\Big[\sum_{j=0}^{t-2}\alpha(1-\alpha)^j y_{t-1-j} + (1-\alpha)^{t-1}\ell_0\Big]. Put i=j+1i = j + 1 in the sum: it becomes ∑i=1t−1α(1−α)iyt−i\sum_{i=1}^{t-1}\alpha(1-\alpha)^{i} y_{t-i}. Adding the term αyt\alpha y_t (the case i=0i = 0) gives the formula for tt.
    3. The weights sum to α∑j=0t−1(1−α)j+(1−α)t=α 1−(1−α)t1−(1−α)+(1−α)t=1\alpha\sum_{j=0}^{t-1}(1-\alpha)^j + (1-\alpha)^t = \alpha\,\frac{1 - (1-\alpha)^t}{1 - (1-\alpha)} + (1-\alpha)^t = 1 (a geometric sum). ■\blacksquare

    So SES is a weighted average of the data and ℓ0\ell_0, and the weight of ℓ0\ell_0 dies out like (1−α)t(1-\alpha)^t.

    Memory. The weights α(1−α)j\alpha(1-\alpha)^j form a geometric distribution over the age jj. Its mean is ∑jj α(1−α)j=(1−α)/α\sum_j j\,\alpha(1-\alpha)^j = (1-\alpha)/\alpha. So the average age of the data in the forecast is (1−α)/α(1-\alpha)/\alpha steps, and roughly the last 1/α1/\alpha observations carry most of the weight. α=0.1\alpha = 0.1: about 10 observations; α=0.5\alpha = 0.5: about 2.

    Quick check

    SES has fitted ℓn=42.7\ell_n = 42.7 at the last observation. What is the forecast for h=10h = 10?

    3.2 Choosing α\alpha and ℓ0\ell_0 #

    The parameters are chosen to make the one-step errors small on the training data:

    SSE(α,ℓ0)=∑t=1n(yt−y^t∣t−1)2=∑t=1net2.\text{SSE}(\alpha, \ell_0) = \sum_{t=1}^{n} \big(y_t - \hat y_{t\mid t-1}\big)^2 = \sum_{t=1}^{n} e_t^2 .

    There is no closed-form minimiser, because y^t∣t−1\hat y_{t\mid t-1} depends on α\alpha through all earlier steps. But SSE is cheap to evaluate (one pass through the data), so a one-dimensional search works: a grid over α∈(0,1]\alpha \in (0, 1], then a bounded scalar minimiser such as golden section or Brent's method (scipy.optimize.minimize_scalar). Libraries estimate ℓ0\ell_0 together with α\alpha, or set it to y1y_1 or to the mean of the first few values.

    What the minimiser finds depends on the data:

    • white noise around a constant mean: the best forecast is the overall mean, so α^\hat\alpha is close to 0 (average everything);
    • a random walk: the best forecast is the last value, so α^\hat\alpha is close to 1;
    • a local level (a slowly wandering mean plus noise): α^\hat\alpha is in between. For the model yt=μt+εty_t = \mu_t + \varepsilon_t, μt=μt−1+ηt\mu_t = \mu_{t-1} + \eta_t with the ratio q=Var⁡(ηt)/Var⁡(εt)q = \operatorname{Var}(\eta_t)/\operatorname{Var}(\varepsilon_t), the best α\alpha is (−q+q2+4q)/2(-q + \sqrt{q^2 + 4q})/2; for q=0.1q = 0.1 this is about 0.27. Lesson 07 derives this formula as the steady-state Kalman gain.
    Interactive figure: loading…

    Drag on the curve to move the current α\alpha. The magenta curve is the SSE of the one-step errors and the orange dot is its minimum. Below, the level follows the data. Before you switch the series, guess where the minimum will be: white noise, random walk, local level.

    3.3 Holt's linear trend and the damped trend #

    Holt's linear trend method (Holt 1957) adds a trend state btb_t, the current slope:

    forecasty^t+h∣t=ℓt+h btlevelℓt=αyt+(1−α)(ℓt−1+bt−1)trendbt=β∗(ℓt−ℓt−1)+(1−β∗) bt−1\begin{aligned} \text{forecast}\quad & \hat y_{t+h\mid t} = \ell_t + h\,b_t \\ \text{level}\quad & \ell_t = \alpha y_t + (1-\alpha)(\ell_{t-1} + b_{t-1}) \\ \text{trend}\quad & b_t = \beta^*(\ell_t - \ell_{t-1}) + (1-\beta^*)\,b_{t-1} \end{aligned}

    with 0<α≤10 < \alpha \le 1 and 0≤β∗≤10 \le \beta^* \le 1. Read the level equation as "a weighted average of the new value and the previous level moved one step along the trend". The trend equation is "a weighted average of the newest change in level and the previous slope".

    In error-correction form, with et=yt−(ℓt−1+bt−1)e_t = y_t - (\ell_{t-1} + b_{t-1}):

    ℓt=ℓt−1+bt−1+αet,bt=bt−1+αβ∗et.\ell_t = \ell_{t-1} + b_{t-1} + \alpha e_t, \qquad b_t = b_{t-1} + \alpha\beta^* e_t .

    (For the trend: ℓt−ℓt−1−bt−1=αet\ell_t - \ell_{t-1} - b_{t-1} = \alpha e_t, so bt=bt−1+β∗(ℓt−ℓt−1−bt−1)=bt−1+αβ∗etb_t = b_{t-1} + \beta^*(\ell_t - \ell_{t-1} - b_{t-1}) = b_{t-1} + \alpha\beta^* e_t.)

    The forecast is a straight line with slope bnb_n. A straight line goes on forever, so at long horizons Holt's forecasts are often too high (or too low). The damped trend method (Gardner and McKenzie 1985) bends the line towards a flat one:

    y^t+h∣t=ℓt+(ϕ+ϕ2+⋯+ϕh) btℓt=αyt+(1−α)(ℓt−1+ϕbt−1)bt=β∗(ℓt−ℓt−1)+(1−β∗) ϕ bt−1\begin{aligned} \hat y_{t+h\mid t} &= \ell_t + (\phi + \phi^2 + \dots + \phi^h)\,b_t \\ \ell_t &= \alpha y_t + (1-\alpha)(\ell_{t-1} + \phi b_{t-1}) \\ b_t &= \beta^*(\ell_t - \ell_{t-1}) + (1-\beta^*)\,\phi\,b_{t-1} \end{aligned}

    with 0<ϕ<10 < \phi < 1. The sum is geometric: ϕ+⋯+ϕh=ϕ(1−ϕh)/(1−ϕ)\phi + \dots + \phi^h = \phi(1 - \phi^h)/(1 - \phi). As h→∞h \to \infty it tends to ϕ/(1−ϕ)\phi/(1-\phi), so the forecast tends to the constant ℓt+ϕ1−ϕ bt\ell_t + \frac{\phi}{1-\phi}\,b_t. With ϕ=1\phi = 1 the method is Holt's method; with ϕ=0\phi = 0 it is SES. In practice ϕ\phi is restricted to 0.8≤ϕ≤0.980.8 \le \phi \le 0.98 (FPP3): below 0.8 the damping is very strong, and above 0.98 the method is almost Holt's. On many business series, damped trend is one of the most accurate single methods (Gardner 2006).

    Quick check

    In the damped trend method you set ϕ=1\phi = 1. Which method do you get?

    3.4 Holt-Winters: adding a season #

    Winters (1960) added seasonal states sts_t with period mm. In the additive method the season is added; it has a fixed size:

    y^t+h∣t=ℓt+h bt+st+h−m(k+1),k=⌊(h−1)/m⌋ℓt=α (yt−st−m)+(1−α)(ℓt−1+bt−1)bt=β∗(ℓt−ℓt−1)+(1−β∗) bt−1st=γ (yt−ℓt−1−bt−1)+(1−γ) st−m\begin{aligned} \hat y_{t+h\mid t} &= \ell_t + h\,b_t + s_{t+h-m(k+1)}, \qquad k = \lfloor (h-1)/m \rfloor \\ \ell_t &= \alpha\,(y_t - s_{t-m}) + (1-\alpha)(\ell_{t-1} + b_{t-1}) \\ b_t &= \beta^*(\ell_t - \ell_{t-1}) + (1-\beta^*)\,b_{t-1} \\ s_t &= \gamma\,(y_t - \ell_{t-1} - b_{t-1}) + (1-\gamma)\,s_{t-m} \end{aligned}

    Each line has a plain meaning:

    • level: a weighted average of the seasonally adjusted value yt−st−my_t - s_{t-m} and the previous level moved along the trend;
    • trend: as in Holt's method;
    • season: a weighted average of the newest seasonal deviation yt−ℓt−1−bt−1y_t - \ell_{t-1} - b_{t-1} and the seasonal state of the same season one period earlier, st−ms_{t-m}.

    The seasonal index. There are mm seasonal states, one per season, and each one is updated once per period. The forecast for horizon hh uses the last updated state of the season of t+ht + h, which is st+h−m(k+1)s_{t+h-m(k+1)}. For h≤mh \le m this is st+h−ms_{t+h-m}; for m<h≤2mm < h \le 2m it is st+h−2ms_{t+h-2m}, the same state again. The integer kk counts the full periods inside the horizon, exactly as for the seasonal naive forecast of lesson 03.

    The usual ranges are 0<α<10 < \alpha < 1, 0<β∗<10 < \beta^* < 1 and 0<γ<1−α0 < \gamma < 1 - \alpha (FPP3, §8.6). With γ=0\gamma = 0, the seasonal states never change: the seasonal pattern is frozen at its start values.

    The multiplicative method is for swings that grow with the level. The season multiplies the level, and the seasonal states are ratios around 1 instead of deviations around 0:

    additive multiplicative
    forecast ℓt+hbt+st+h−m(k+1)\ell_t + h b_t + s_{t+h-m(k+1)} (ℓt+hbt) st+h−m(k+1)(\ell_t + h b_t)\, s_{t+h-m(k+1)}
    level α(yt−st−m)+(1−α)(ℓt−1+bt−1)\alpha(y_t - s_{t-m}) + (1-\alpha)(\ell_{t-1} + b_{t-1}) α yt/st−m+(1−α)(ℓt−1+bt−1)\alpha\, y_t / s_{t-m} + (1-\alpha)(\ell_{t-1} + b_{t-1})
    trend β∗(ℓt−ℓt−1)+(1−β∗) bt−1\beta^*(\ell_t - \ell_{t-1}) + (1-\beta^*)\, b_{t-1} the same
    season γ(yt−ℓt−1−bt−1)+(1−γ) st−m\gamma(y_t - \ell_{t-1} - b_{t-1}) + (1-\gamma)\, s_{t-m} γ yt/(ℓt−1+bt−1)+(1−γ) st−m\gamma\, y_t / (\ell_{t-1} + b_{t-1}) + (1-\gamma)\, s_{t-m}
    seasonal states sum to about 0 over one period average about 1 over one period

    The damped versions replace bt−1b_{t-1} by ϕbt−1\phi b_{t-1} and hbth b_t by (ϕ+⋯+ϕh)bt(\phi + \dots + \phi^h) b_t. A third option for growing swings: take logarithms (lesson 01) and use the additive method on log⁡yt\log y_t.

    Start values. The recursions need ℓ\ell, bb and mm seasonal states before the first update. A simple rule, used in the figures and the notebook of this lesson, uses the first two periods. Let yˉ(1)\bar y^{(1)} and yˉ(2)\bar y^{(2)} be the means of the first and the second period. Then b=(yˉ(2)−yˉ(1))/mb = (\bar y^{(2)} - \bar y^{(1)})/m; the level at the end of the first period is ℓ=yˉ(1)+b (m−1)/2\ell = \bar y^{(1)} + b\,(m-1)/2; and the seasonal states are the first period's values minus the trend line, si=yi−(yˉ(1)+b (i−(m+1)/2))s_i = y_i - (\bar y^{(1)} + b\,(i - (m+1)/2)) for i=1,…,mi = 1, \dots, m (divide instead of subtract for the multiplicative method). The updates start at t=m+1t = m + 1. Libraries usually estimate the start values together with the parameters.

    Interactive figure: loading…

    Pick a model and move its parameters. The training data are the blue line, the test data the blue dots, and the forecast starts at the origin with its 95 % interval (orange band). "Fit" minimises the SSE of the one-step errors on the training part. Notice: SES is flat, Holt's line follows the last swing, damping bends the line, and only the Holt-Winters methods follow the season. Set γ=0\gamma = 0 to freeze the seasonal pattern. On the "growing swings" data compare the additive and the multiplicative method.

    Quick check

    Monthly sales of a growing company: the difference between the December peak and the February low doubles when the sales level doubles. Which model fits best?

    3.5 ETS: exponential smoothing as a state-space model #

    So far exponential smoothing is a recipe: equations that produce point forecasts. To get a likelihood and prediction intervals we need a statistical model: a rule that says how the data are generated, including the randomness.

    ETS(A,N,N): the model behind SES. Let εt\varepsilon_t be independent N(0,σ2)\mathcal N(0, \sigma^2) errors. The innovations state-space model is

    observation equationyt=ℓt−1+εtstate equationℓt=ℓt−1+α εt.\begin{aligned} \text{observation equation}\quad & y_t = \ell_{t-1} + \varepsilon_t \\ \text{state equation}\quad & \ell_t = \ell_{t-1} + \alpha\,\varepsilon_t . \end{aligned}

    The state ℓt−1\ell_{t-1} is the one-step forecast, and εt=yt−ℓt−1\varepsilon_t = y_t - \ell_{t-1} is the one-step error ete_t of SES. So the model generates exactly the SES recursions: the point forecasts of ETS(A,N,N) are the SES forecasts. The same error εt\varepsilon_t drives both equations (one source of randomness); such errors are called innovations.

    The name ETS. ETS stands for (Error, Trend, Seasonal), and also for "ExponenTial Smoothing". Each letter is a component:

    • Error: A (additive) or M (multiplicative, yt=y^t∣t−1(1+εt)y_t = \hat y_{t\mid t-1}(1 + \varepsilon_t));
    • Trend: N (none), A (additive) or Ad\mathrm{A_d} (additive damped);
    • Seasonal: N, A or M.

    So SES is ETS(A,N,N) or ETS(M,N,N); Holt is ETS(A,A,N); damped trend is ETS(A,Ad\mathrm{A_d},N); additive Holt-Winters is ETS(A,A,A); multiplicative Holt-Winters is ETS(M,A,M). There are 2×3×3=182 \times 3 \times 3 = 18 combinations (FPP3, §8.5). Three of them, ETS(A,N,M), ETS(A,A,M) and ETS(A,Ad\mathrm{A_d},M), can be numerically unstable (they divide by states that can be close to 0), so automatic selection usually skips them (FPP3, §8.6). Additive and multiplicative errors give the same point forecasts but different intervals.

    What the model adds.

    1. A likelihood. For additive errors, log⁡L=−n2log⁡(2πσ2)−12σ2∑tεt2\log L = -\frac{n}{2}\log(2\pi\sigma^2) - \frac{1}{2\sigma^2}\sum_t \varepsilon_t^2. Maximising over σ2\sigma^2 gives σ^2=SSE/n\hat\sigma^2 = \text{SSE}/n, and then maximising the likelihood is the same as minimising the SSE. For multiplicative errors the likelihood has an extra term, so the two criteria differ.
    2. Model selection. With a likelihood you can compare different models with the AIC, −2log⁡L+2k-2\log L + 2k (or the corrected AICc), where kk counts the parameters, the start values and σ2\sigma^2. Automatic ETS (AutoETS, ets()) fits all allowed models and keeps the one with the smallest AICc. The SSE cannot do this: a model with more states always has a smaller SSE.
    3. Prediction intervals. The model says how far the future can move. This needs the distribution of the future errors, derived next.

    Theorem (ETS(A,N,N) forecast variance). For ETS(A,N,N), the hh-step forecast error has mean 0 and variance

    Var⁡(yn+h−ℓn∣y1,…,yn)=σ2[1+α2(h−1)].\operatorname{Var}\big(y_{n+h} - \ell_n \mid y_1, \dots, y_n\big) = \sigma^2\big[1 + \alpha^2(h - 1)\big].

    Proof.

    1. Apply the state equation jj times: ℓn+j=ℓn+α(εn+1+⋯+εn+j)\ell_{n+j} = \ell_n + \alpha(\varepsilon_{n+1} + \dots + \varepsilon_{n+j}).
    2. The observation equation at time n+hn + h gives yn+h=ℓn+h−1+εn+h=ℓn+α∑i=1h−1εn+i+εn+hy_{n+h} = \ell_{n+h-1} + \varepsilon_{n+h} = \ell_n + \alpha\sum_{i=1}^{h-1}\varepsilon_{n+i} + \varepsilon_{n+h}.
    3. The future errors are independent of the past and of each other, with mean 0. So the conditional mean is ℓn\ell_n (the SES forecast), and the variance is α2(h−1)σ2+σ2\alpha^2(h-1)\sigma^2 + \sigma^2. ■\blacksquare

    A 95 % prediction interval is ℓn±1.96 σ^1+α2(h−1)\ell_n \pm 1.96\,\hat\sigma\sqrt{1 + \alpha^2(h-1)}. With α=1\alpha = 1 this is the naive forecast's σ^h\hat\sigma\sqrt h from lesson 03; with small α\alpha the interval grows slowly, because a single shock moves the level only a little.

    The same argument works for every model with additive errors and no multiplicative part: the hh-step error is εn+h+∑j=1h−1cj εn+h−j\varepsilon_{n+h} + \sum_{j=1}^{h-1} c_j\,\varepsilon_{n+h-j}, where cjc_j is the effect of one unit of error on the forecast jj steps later, so the variance is σ2(1+∑j=1h−1cj2)\sigma^2\big(1 + \sum_{j=1}^{h-1} c_j^2\big). For Holt's method cj=α(1+β∗j)c_j = \alpha(1 + \beta^* j); for additive Holt-Winters an extra γ\gamma is added when jj is a multiple of mm. FPP3 Table 8.7 lists the closed forms. For multiplicative models there is no simple formula; libraries simulate many future paths, as the figure above does for the multiplicative method.

    Error correction, step by step. Additive Holt-Winters in error-correction form (ETS(A,A,A)): with et=yt−(ℓt−1+bt−1+st−m)e_t = y_t - (\ell_{t-1} + b_{t-1} + s_{t-m}),

    ℓt=ℓt−1+bt−1+αet,bt=bt−1+αβ∗et,st=st−m+γet.\ell_t = \ell_{t-1} + b_{t-1} + \alpha e_t, \qquad b_t = b_{t-1} + \alpha\beta^* e_t, \qquad s_t = s_{t-m} + \gamma e_t .

    Each state is its prediction plus a gain times the one-step error. The gains are α\alpha, αβ∗\alpha\beta^* and γ\gamma.

    Interactive figure: loading…

    Step through time on the monthly CO₂ series (Mauna Loa, 1980–2001). At each month the one-step forecast meets the data; the error moves the level, the trend (middle panel) and the seasonal state (bottom panel), each by its gain times the error. The equations below the figure show the numbers. Parameters: α=0.54\alpha = 0.54, β∗=0.005\beta^* = 0.005, γ=0.19\gamma = 0.19, fitted by least squares. Notice how small the trend gain αβ∗≈0.003\alpha\beta^* \approx 0.003 is: the slope of CO₂ is very stable.

    Quick check

    In additive Holt-Winters you set γ=0\gamma = 0. What happens?

    SES is ARIMA(0,1,1), and the Kalman filter of a local level model

    From yt=ℓt−1+ety_t = \ell_{t-1} + e_t and ℓt=ℓt−1+αet\ell_t = \ell_{t-1} + \alpha e_t: yt−yt−1=(ℓt−1+et)−(ℓt−2+et−1)=αet−1+et−et−1y_t - y_{t-1} = (\ell_{t-1} + e_t) - (\ell_{t-2} + e_{t-1}) = \alpha e_{t-1} + e_t - e_{t-1}. So

    yt−yt−1=et+(α−1) et−1,y_t - y_{t-1} = e_t + (\alpha - 1)\,e_{t-1},

    which is an ARIMA(0,1,1) model with MA coefficient θ=α−1\theta = \alpha - 1 (lesson 06, plus-sign convention). Every additive ETS model without a multiplicative part is a special case of an ARIMA model in this way.

    The local level model yt=μt+εty_t = \mu_t + \varepsilon_t, μt=μt−1+ηt\mu_t = \mu_{t-1} + \eta_t has two independent noise sources. Its Kalman filter (lesson 07) updates the estimate of μt\mu_t as "prediction + gain × innovation", and the gain converges to a constant. In the steady state the filter is SES with α\alpha equal to that gain, (−q+q2+4q)/2(-q + \sqrt{q^2 + 4q})/2.

    3.6 How well does it work? A backtest on CO₂ #

    We fit the parameters of each method once on the first 120 months of the CO₂ data (1980–1989), by minimising the SSE. Then we run a rolling origin with an expanding window: at the origins 120, 132, …, 252 (12 folds, one per year), the states are updated with all data up to the origin and we forecast the next 12 months. The table gives the MASE, averaged over the 12 folds and the 12 horizons (lesson 03).

    Method ETS form MASE
    seasonal naive — 1.00
    SES ETS(A,N,N) 1.41
    Holt ETS(A,A,N) 4.93
    damped trend ETS(A,Ad\mathrm{A_d},N) 1.71
    Holt-Winters additive ETS(A,A,A) 0.27
    Holt-Winters multiplicative ETS(M,A,M) 0.27

    The non-seasonal methods lose to the seasonal naive benchmark, because CO₂ has a strong yearly cycle. Holt's method is the worst: fitted to seasonal data, its slope follows the last month-to-month swing (its fitted α\alpha and β∗\beta^* are near 1) and the straight line extrapolates it. Both Holt-Winters methods cut the error of the seasonal naive forecast by about three quarters. Additive and multiplicative are equally good here: the seasonal swings of CO₂ (about ±3 ppm on a level of 340–370 ppm) barely change in size. Damping, often a good default, does not help a series with a steady trend.

    (Keeping the parameters fixed and only updating the states is a common, cheap backtest. Refitting the parameters at every origin is more expensive and closer to production; both are honest because the parameters never see data after the origin.)

    Answers to section 1. (1) 0.5⋅0.53=0.06250.5 \cdot 0.5^3 = 0.0625 (the newest value has weight 0.5, then 0.25, 0.125, 0.0625). (2) A flat line at the last level. SES has no trend state; on trending data the level also lags behind the data, so the flat forecasts are too low (for an upward trend) and get worse with the horizon. Use Holt's or the damped trend method. (3) Multiplicative (or additive on the log scale).

    4. Worked example #

    (a) SES by hand. α=0.5\alpha = 0.5, ℓ0=10\ell_0 = 10, data y1,…,y4=12,9,13,11y_1, \dots, y_4 = 12, 9, 13, 11.

    tt yty_t forecast ℓt−1\ell_{t-1} error ete_t ℓt=ℓt−1+0.5 et\ell_t = \ell_{t-1} + 0.5\,e_t
    1 12 10 2 11
    2 9 11 −2 10
    3 13 10 3 11.5
    4 11 11.5 −0.5 11.25

    The forecast for every horizon is ℓ4=11.25\ell_4 = 11.25. Check with the weighted-average form:

    0.5⋅11+0.25⋅13+0.125⋅9+0.0625⋅12+0.0625⋅10=5.5+3.25+1.125+0.75+0.625=11.25.0.5 \cdot 11 + 0.25 \cdot 13 + 0.125 \cdot 9 + 0.0625 \cdot 12 + 0.0625 \cdot 10 = 5.5 + 3.25 + 1.125 + 0.75 + 0.625 = 11.25 .

    The weights are 0.5,0.25,0.125,0.06250.5, 0.25, 0.125, 0.0625 for y4,y3,y2,y1y_4, y_3, y_2, y_1, and (1−0.5)4=0.0625(1 - 0.5)^4 = 0.0625 for ℓ0\ell_0; they sum to 1.

    Interval. SSE =4+4+9+0.25=17.25= 4 + 4 + 9 + 0.25 = 17.25, so σ^2=17.25/4=4.3125\hat\sigma^2 = 17.25/4 = 4.3125 and σ^≈2.077\hat\sigma \approx 2.077. For h=1h = 1: 11.25±1.96⋅2.077=11.25±4.0711.25 \pm 1.96 \cdot 2.077 = 11.25 \pm 4.07. For h=3h = 3: 1+0.25⋅2=1.5≈1.225\sqrt{1 + 0.25 \cdot 2} = \sqrt{1.5} \approx 1.225, so 11.25±4.9911.25 \pm 4.99. (With only four observations this is only an illustration: σ^\hat\sigma is very uncertain.)

    (b) Holt by hand. α=0.5\alpha = 0.5, β∗=0.4\beta^* = 0.4 (so the trend gain is αβ∗=0.2\alpha\beta^* = 0.2), ℓ0=10\ell_0 = 10, b0=1b_0 = 1, data 11.5,12,1411.5, 12, 14.

    tt yty_t forecast ℓt−1+bt−1\ell_{t-1} + b_{t-1} ete_t ℓt=forecast+0.5 et\ell_t = \text{forecast} + 0.5\,e_t bt=bt−1+0.2 etb_t = b_{t-1} + 0.2\,e_t
    1 11.5 11 0.5 11.25 1.1
    2 12 12.35 −0.35 12.175 1.03
    3 14 13.205 0.795 13.6025 1.189

    Check step 1 with the component form: ℓ1=0.5⋅11.5+0.5 (10+1)=11.25\ell_1 = 0.5 \cdot 11.5 + 0.5\,(10 + 1) = 11.25 and b1=0.4 (11.25−10)+0.6⋅1=0.5+0.6=1.1b_1 = 0.4\,(11.25 - 10) + 0.6 \cdot 1 = 0.5 + 0.6 = 1.1. The forecasts are the line 13.6025+1.189 h13.6025 + 1.189\,h: 14.79,15.98,17.1714.79, 15.98, 17.17 for h=1,2,3h = 1, 2, 3.

    (c) Damped forecasts. Suppose a damped trend fit ends with ℓn=13.6\ell_n = 13.6, bn=1.2b_n = 1.2 and ϕ=0.9\phi = 0.9.

    hh ϕ+⋯+ϕh\phi + \dots + \phi^h damped forecast Holt line ℓn+hbn\ell_n + h b_n
    1 0.9 14.68 14.8
    2 1.71 15.65 16.0
    10 9(1−0.910)≈5.869(1 - 0.9^{10}) \approx 5.86 20.63 25.6
    ∞\infty 0.9/0.1=90.9/0.1 = 9 24.4 ∞\infty

    (d) Which seasonal state? Quarterly data, m=4m = 4, origin nn. The forecast for horizon hh uses sn+h−4(k+1)s_{n+h-4(k+1)} with k=⌊(h−1)/4⌋k = \lfloor (h-1)/4 \rfloor:

    hh 1 2 3 4 5 6
    kk 0 0 0 0 1 1
    state sn−3s_{n-3} sn−2s_{n-2} sn−1s_{n-1} sns_n sn−3s_{n-3} sn−2s_{n-2}

    Horizons hh and h+4h + 4 use the same state: the last estimate of that quarter.

    5. In code #

    NumPy reproduces the worked examples and checks the ETS(A,N,N) interval by simulation. The notebook has these cells, a general ETS function and the exercises.

    import numpy as np
    
    def ses(y, alpha, l0):
        l, levels = l0, []
        for v in y:
            l = l + alpha * (v - l)          # error-correction form
            levels.append(l)
        return np.array(levels)
    
    y = np.array([12, 9, 13, 11.])
    print(ses(y, 0.5, 10.0))                                   # [11.   10.   11.5  11.25]
    w = 0.5 * 0.5 ** np.arange(4)                              # weights of y4, y3, y2, y1
    print(w @ y[::-1] + 0.5**4 * 10.0)                         # 11.25
    
    # Holt, error-correction form
    l, b, alpha, beta_star = 10.0, 1.0, 0.5, 0.4
    for v in [11.5, 12, 14]:
        e = v - (l + b)
        l, b = l + b + alpha * e, b + alpha * beta_star * e
    print(round(l, 4), round(b, 4), np.round(l + b * np.arange(1, 4), 4))
    # 13.6025 1.189 [14.7915 15.9805 17.1695]
    
    # ETS(A,N,N): simulate 200000 futures and compare the h-step variance with 1 + alpha^2 (h - 1)
    rng = np.random.default_rng(0)
    alpha, H, N = 0.3, 6, 200_000
    eps = rng.normal(size=(N, H))
    level = np.zeros(N)
    ys = np.empty((N, H))
    for k in range(H):
        ys[:, k] = level + eps[:, k]          # y = previous level + error
        level = level + alpha * eps[:, k]     # level update
    print(np.round(ys.var(axis=0), 3))                        # [1.001 1.088 1.183 1.268 1.357 1.447]
    print(1 + alpha**2 * np.arange(H))                        # [1.   1.09 1.18 1.27 1.36 1.45]
    

    With statsmodels installed, ETSModel(y, error="add", trend="add", seasonal="add", seasonal_periods=12) fits ETS(A,A,A) by maximum likelihood; with the same parameters and start values it gives the same fitted values and forecasts as the recursions above (the notebook checks this).

    6. Where it shows up #

    • Demand planning and inventory. Retail and supply-chain systems forecast thousands of items with ETS models chosen automatically by AICc; the prediction intervals set safety stocks.
    • Benchmarks for ML. The M4 "Comb" benchmark (SES, Holt and damped trend, averaged) and automatic ETS are the standard statistical baselines in papers on machine learning for forecasting (lessons 08 and 09).
    • Hybrid models. ES-RNN, the winner of M4, used Holt-Winters-style level and seasonal states to normalise each series and an LSTM to forecast the normalised values (Smyl 2020).
    • Smoothing in machine learning. The exponential moving average is SES under another name: the running statistics of batch normalisation, the moment estimates of Adam (optimization lesson 06), and EMA weights of trained models all use ℓt=β ℓt−1+(1−β) xt\ell_t = \beta\,\ell_{t-1} + (1 - \beta)\,x_t, that is SES with α=1−β\alpha = 1 - \beta.
    • Monitoring and science. EWMA control charts in quality control and anomaly detection (lesson 11) smooth a signal with SES; sensor and environmental data are often gap-filled and smoothed with Holt-Winters before analysis.

    7. Common mistakes #

    • Using SES on trending or seasonal data. Its forecast is flat and lags behind a trend. Use Holt, damped trend or Holt-Winters, and compare with the seasonal naive forecast.
    • Forgetting that Holt's line never bends. Long-horizon forecasts of Holt's method often overshoot; try the damped trend.
    • Confusing β∗\beta^* and β\beta. In component form the trend parameter is β∗\beta^*; in ETS state-space form the trend gain is β=αβ∗\beta = \alpha\beta^*. Check which one a library reports (ETSModel reports β\beta).
    • Choosing additive seasonality for growing swings. Look at the plot (lesson 01): if the swings grow with the level, use the multiplicative method or a log transform.
    • Picking the model with the smallest SSE. More states always fit better in-sample. Compare models with AICc or, better, with a rolling-origin backtest.
    • Reading the seasonal index wrongly. The forecast at horizon hh uses sn+h−m(k+1)s_{n+h-m(k+1)}, the last estimate of that season, not sn+h−ms_{n+h-m} for h>mh > m (which lies in the future).
    • Treating the recursions as the model. Without the ETS error model there is no likelihood and no valid interval. A "±1.96 σ" band with constant width ignores that the error grows with hh.

    8. Check yourself #

    1. Show that α=1\alpha = 1 turns SES into the naive method, and say what α→0\alpha \to 0 does.
      AnswerWith α=1\alpha = 1, ℓt=yt\ell_t = y_t, so the forecast is the last value. As α→0\alpha \to 0 the level barely moves: the forecast stays near ℓ0\ell_0. If ℓ0\ell_0 is the mean of the data, SES with very small α\alpha behaves like the mean method.
    2. A series has the SSE-optimal α=0.95\alpha = 0.95. What does this tell you about the series, and which benchmark will SES resemble?
      AnswerThe best forecast is almost the last value: the series behaves like a random walk (or has a trend or season that SES cannot follow, so it chases the last value). SES then almost equals the naive forecast. If there is a trend or season, try Holt or Holt-Winters.
    3. Damped trend with ℓn=50\ell_n = 50, bn=2b_n = 2, ϕ=0.8\phi = 0.8. Give the forecasts for h=1h = 1 and h=2h = 2, and the limit as h→∞h \to \infty.
      Answerh=1h = 1: 50+0.8⋅2=51.650 + 0.8 \cdot 2 = 51.6. h=2h = 2: 50+(0.8+0.64)⋅2=52.8850 + (0.8 + 0.64) \cdot 2 = 52.88. Limit: 50+0.80.2⋅2=5850 + \frac{0.8}{0.2} \cdot 2 = 58.
    4. Monthly data, m=12m = 12, origin nn. Which seasonal state does additive Holt-Winters use for h=13h = 13 and for h=24h = 24?
      Answerh=13h = 13: k=⌊12/12⌋=1k = \lfloor 12/12 \rfloor = 1, state sn+13−24=sn−11s_{n+13-24} = s_{n-11}, the same as for h=1h = 1. h=24h = 24: k=⌊23/12⌋=1k = \lfloor 23/12 \rfloor = 1, state sn+24−24=sns_{n+24-24} = s_n, the same as for h=12h = 12.
    5. Why does ETS give prediction intervals while the Holt-Winters recursions alone do not?
      AnswerThe recursions only produce point forecasts. ETS adds a probability model for the errors (εt\varepsilon_t independent N(0,σ2)\mathcal N(0, \sigma^2), entering the observation and the state equations). From this model the distribution of yn+hy_{n+h} follows: for ETS(A,N,N) its variance is σ2[1+α2(h−1)]\sigma^2[1 + \alpha^2(h-1)].
    6. For ETS(A,N,N) with α=0.2\alpha = 0.2 and σ^=3\hat\sigma = 3, how wide is the 95 % interval at h=1h = 1 and at h=26h = 26?
      Answerh=1h = 1: ±1.96⋅3=±5.88\pm 1.96 \cdot 3 = \pm 5.88. h=26h = 26: 1+0.04⋅25=21 + 0.04 \cdot 25 = 2, so ±1.96⋅32≈±8.32\pm 1.96 \cdot 3\sqrt 2 \approx \pm 8.32.
    Recall cardsAnswer in your head first, then reveal. Add the cards to your review deck to see them again just before you would forget.
    1. Write SES in component form and in error-correction form.

    2. What weight does SES give to yt−jy_{t-j}?

    3. About how many recent observations carry most of the weight in SES?

    4. How are the SES parameters usually chosen?

    5. Write Holt's forecast and the damped trend forecast.

    6. Which seasonal state does Holt-Winters use at horizon hh?

    7. What does ETS stand for, and what is ETS(A,N,N)?

    8. Why does ETS give prediction intervals and the Holt-Winters recursions alone do not?

    9. What is the hh-step forecast variance of ETS(A,N,N)?

    10. Additive or multiplicative seasonality: how do you choose?

    Open the review →

    9. Interview angle #

    • "Explain exponential smoothing in one minute." — A weighted average of the past with weights α(1−α)j\alpha(1-\alpha)^j; equivalently a level updated by α\alpha times the forecast error. Holt adds a trend state, Winters a seasonal state; ETS adds an error model, which gives a likelihood and intervals.
    • "How would you choose α\alpha?" — Minimise the one-step SSE (maximum likelihood for additive errors) on the training data, then check with a rolling-origin backtest.
    • "SES vs ARIMA?" — SES is ARIMA(0,1,1) with θ=α−1\theta = \alpha - 1; additive ETS models are special ARIMA models, while multiplicative ETS models have no ARIMA equivalent.
    • "What is an exponential moving average in deep learning?" — SES: Adam's moment estimates, batch-norm running statistics and EMA of weights all use ℓt=βℓt−1+(1−β)xt\ell_t = \beta\ell_{t-1} + (1-\beta)x_t.
    • "Your Holt forecast explodes after a few months. What do you do?" — Use a damped trend (ϕ≈0.9\phi \approx 0.9), check whether the series is seasonal (Holt chases seasonal swings), and compare with seasonal naive in a backtest.

    10. Practice #

    The notebook for this lesson runs in Colab. It has five exercises, each with a check cell and a folded solution:

    1. Write ses(y, alpha, l0) that returns the levels and the one-step forecasts, and check it against the weighted-average formula.
    2. Write fit_ses(y): a grid over α\alpha followed by scipy.optimize.minimize_scalar on the SSE. Recover α≈0.27\alpha \approx 0.27 on a simulated local-level series.
    3. Write holt_winters_additive(y, m, alpha, beta, gamma, H) and check that it reproduces a series built exactly from level, trend and season.
    4. Write the damped trend forecast and show that it converges to ℓt+ϕ1−ϕbt\ell_t + \frac{\phi}{1-\phi} b_t.
    5. Backtest SES, Holt, damped trend and Holt-Winters against seasonal naive on the CO₂ data with the rolling origin of lesson 03 (and, if statsmodels is installed, compare with ETSModel).

    11. Watch and read #

    The weighted average, the component form and how alpha and the start level are estimated.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    Holt's linear trend and the damped trend on real data.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    Additive and multiplicative Holt-Winters, and how to choose between them.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    How an error model turns the recursions into ETS, with a likelihood.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play
    A short overview of the whole family, from SES to Holt-Winters.
    Open on YouTube · the player loads from youtube-nocookie.com when you press play