datarekha

Exponential smoothing & Holt-Winters

Learn how Simple Exponential Smoothing, Holt's method, and Holt-Winters build up a fast, robust forecaster by weighting recent data more heavily — and when this ETS family beats ARIMA.

9 min read Intermediate Time Series Lesson 11 of 14

What you'll learn

  • How SES weights recent observations exponentially so that older data fades smoothly into the past
  • How Holt's method adds a trend component (beta) and Holt-Winters adds seasonality (gamma)
  • ETS vs ARIMA: when to reach for each, and why strong clear seasonality often tips the balance

Before you start

The classical chapter ended on a complaint: ARIMA and VAR are powerful but heavystationarity tests, order hunts, residual diagnostics, all per series. This chapter opens the lighter path, and this lesson is the first model on it.

No — you don’t always need full ARIMA. The exponential smoothing family, also called ETS (Error-Trend-Seasonal), is a collection of models that are fast to fit, easy to interpret, and surprisingly competitive with ARIMA on real-world data. The core idea is beautifully simple: weight observations so that the most recent value matters most and every older value matters a little less, with the influence decaying exponentially into the past.

Simple Exponential Smoothing (SES)

Simple Exponential Smoothing produces a forecast by maintaining a single running estimate called the level, updated after every new observation.

The recursive update rule is:

level_t = alpha * y_t + (1 - alpha) * level_(t-1)

  • y_t is the observed value at time t.
  • level_(t-1) is the level estimate from the previous step — a smoothed summary of all earlier history.
  • alpha (the smoothing parameter) lives in the interval (0, 1) and controls how fast the memory fades.

When alpha is close to 1, the level lunges toward each new observation — the model is reactive but noisy. When alpha is close to 0, the level barely moves — the model is stable but slow to track genuine shifts. The one-step-ahead forecast is simply the current level: forecast_(t+1) = level_t.

Why this is genuinely exponential

Unrolling the recursion shows what is happening under the hood. The current level is:

level_t = alpha * y_t + alpha*(1-alpha)*y_(t-1) + alpha*(1-alpha)^2*y_(t-2) + ...

Every additional lag picks up another factor of (1-alpha). Because (1-alpha) is less than 1, those factors shrink toward zero — an exponential decay of weights as you look further into the past. The diagram below shows this visually.

tt-1t-2t-3t-4t-5t-6Weight assigned to each past observation
Each bar is alpha * (1-alpha)^k for lag k. With alpha = 0.4, the most-recent observation carries 40 % of the weight; three lags back it is down to about 14 %.

Holt’s method — adding a trend

Holt’s method (also called double exponential smoothing) extends SES by tracking two quantities:

  • Level l_t — the smoothed baseline, updated with smoothing parameter alpha.
  • Trend b_t — the smoothed slope (rate of change), updated with smoothing parameter beta.

The forecast h steps ahead is l_t + h * b_t: start from the current level and project along the current trend. Beta, like alpha, lives in (0, 1) and controls how quickly the model revises its trend estimate.

Holt-Winters — adding seasonality

Holt-Winters (also called triple exponential smoothing) adds a third set of smoothed quantities: seasonal indices s_t, one for each period within the season (twelve values for monthly data with annual seasonality, seven for daily data with weekly seasonality).

A third smoothing parameter gamma controls how fast the seasonal indices adapt. The seasonal_periods parameter tells the model the length of one seasonal cycle.

There are two variants:

  • Additive — the seasonal component is added to the level. Use this when the size of seasonal swings stays roughly constant regardless of the level of the series.
  • Multiplicative — the seasonal component multiplies the level. Use this when seasonal swings grow proportionally as the level rises (common in retail and tourism data).

Together the three parameters — alpha for level, beta for trend, gamma for seasonality — define what the forecasting community calls the ETS (Error-Trend-Seasonal) model family. The “E” refers to the error structure (additive or multiplicative), and every combination of (E, T, S) specification is a distinct model in the family.

Implement SES by hand

import numpy as np
import matplotlib.pyplot as plt

np.random.seed(0)

# Simulate a noisy series with a gradual upward drift
n = 60
time = np.arange(n)
series = 10 + 0.3 * time + np.random.randn(n) * 2.5

def ses(y, alpha):
    """Return the level (smoothed) series for a given alpha."""
    level = np.empty(len(y))
    level[0] = y[0]          # initialise with the first observation
    for t in range(1, len(y)):
        level[t] = alpha * y[t] + (1 - alpha) * level[t - 1]
    return level

level_high = ses(series, alpha=0.8)   # reactive
level_low  = ses(series, alpha=0.1)   # stable

fig, ax = plt.subplots(figsize=(9, 4))
ax.plot(time, series,     color="gray",  alpha=0.5, label="observed")
ax.plot(time, level_high, color="#e07b39", linewidth=2, label="SES alpha=0.8 (reactive)")
ax.plot(time, level_low,  color="#4c9be8", linewidth=2, label="SES alpha=0.1 (stable)")
ax.set_xlabel("Time"); ax.set_ylabel("Value")
ax.set_title("Simple Exponential Smoothing — effect of alpha")
ax.legend()
plt.tight_layout()
plt.show()
A noisy upward-drifting series in gray, overlaid by two smoothed level lines: an orange alpha=0.8 line that closely hugs every bump, and a blue alpha=0.1 line that is much smoother and lags behind the data.

High alpha (orange, 0.8) hugs every bump; low alpha (blue, 0.1) glides smoothly past the noise — and lags genuine shifts.

The orange line (alpha=0.8) hugs every bump in the data, while the blue line (alpha=0.1) glides smoothly past most of the noise. Neither is universally better — the right alpha depends on how much of the observed variability is signal versus noise. (For a volatile stock you’d usually want the smoother low-alpha line; for a baseline that genuinely shifts, the reactive high-alpha one.)

Fitting Holt-Winters with statsmodels

For production use you should let statsmodels fit the smoothing parameters automatically by minimizing the sum of squared one-step forecast errors.

from statsmodels.tsa.holtwinters import ExponentialSmoothing
import pandas as pd

# Assume `series` is a pandas Series with a DatetimeIndex and freq="MS"
model = ExponentialSmoothing(
    series,
    trend="add",            # additive trend (use "mul" for multiplicative)
    seasonal="add",         # additive seasonality
    seasonal_periods=12,    # 12 months per year
)
fit = model.fit()

forecast = fit.forecast(steps=12)   # 12-month horizon
print(fit.summary())

On a monthly series with a clear yearly cycle, the additive Holt-Winters forecast carries the trend and the season forward — no differencing, no order hunt, one model call:

Eight years of monthly data rising with a steady yearly cycle. Past a dashed cutoff, a red Holt-Winters forecast for the next 24 months continues both the upward trend and the seasonal humps.

Holt-Winters (additive trend + additive seasonal): the 24-month forecast extends both the trend and the yearly cycle — like SARIMA, but with no stationarity tests or ACF/PACF hunt.

That is the appeal of the ETS family in one picture: a forecast that respects trend and seasonality, produced from three interpretable smoothing knobs that statsmodels tunes for you.

When ETS beats ARIMA

Both ARIMA and ETS are serious, widely-used forecasters. The practical rule of thumb:

SituationLean toward
Strong, clear seasonalityETS (Holt-Winters)
Many series to forecast automaticallyETS (fewer assumptions to tune)
Complex autocorrelation structure in residualsARIMA
Irregular, non-calendar-aligned dataARIMA
Speed and interpretability matter mostETS

ETS tends to shine when the seasonal pattern is stable and predictable — monthly retail, yearly energy demand, weekly call-center volume. ARIMA tends to win when the dynamics are driven by lagged shocks rather than a smooth underlying level-plus-trend-plus-season structure. In practice, the best strategy is to fit both and compare out-of-sample error on a held-out validation window.

In one breath

The exponential smoothing / ETS family forecasts by weighting recent observations more than old ones, decaying exponentially into the past. Simple Exponential Smoothing tracks one level updated as level_t = alpha·y_t + (1−alpha)·level_(t−1) — high alpha is reactive-but-jumpy, low alpha is smooth-but-laggy — and forecasts a flat line, so it has no trend or seasonality. Holt’s method adds a smoothed trend (parameter beta); Holt-Winters adds seasonal indices (parameter gamma, plus seasonal_periods), in additive or multiplicative form. Together (alpha, beta, gamma) define the ETS family, and statsmodels optimises them for you. Reach for ETS over ARIMA when seasonality is strong and clear or when you must forecast many series fast; reach for ARIMA when the dynamics live in lagged shocks — and when unsure, fit both and compare on a held-out window.

Practice

Quick check

0/3
Q1A colleague sets alpha = 0.05 for a Simple Exponential Smoothing model on daily website traffic. What is the most likely consequence?
Q2Monthly ice-cream sales have a pronounced summer peak that grows each year alongside overall sales volume. Which Holt-Winters configuration is most appropriate?
Q3You are building a system to automatically forecast demand for 5 000 products every week. You have minimal time for manual model tuning. Which statement best justifies preferring ETS over ARIMA in this scenario?

A question to carry forward

ETS made forecasting lighter — three knobs, fitted automatically. But it still assumes a tidy world: one clean seasonal period, a smooth level-plus-trend, no awkward gaps or one-off events. Real business series are messier. They often have two seasonalities at once (weekly and yearly), irregular holidays that don’t sit on a fixed lag, missing days, and abrupt level shifts when a product relaunches.

So the question to carry forward is: is there a forecaster built for that mess — one a non-specialist can point at a raw daily series and get a sensible, holiday-aware forecast without tuning anything? The next lesson is Prophet, Meta’s decomposition-based model designed for exactly these business time series: multiple seasonalities, a built-in holiday calendar, robustness to gaps and outliers, and interpretable trend-changepoints — forecasting for people who don’t want to become time-series experts first.

Sign in to track your progress

Completed lessons, your XP, level, and streak save to your account — it's free and takes a few seconds.

Practice this in an interview

All questions
What is exponential smoothing, and how does Holt-Winters extend it to handle trend and seasonality?

Simple exponential smoothing computes a weighted average of all past observations where weights decay geometrically, controlled by a single smoothing parameter alpha. Holt's method adds a trend component with a second parameter beta; Holt-Winters (ETS) adds a seasonal component with a third parameter gamma, making it a strong baseline for series with both trend and seasonality.

When would you choose Prophet over ARIMA for a forecasting problem?

Prophet is a curve-fitting model that decomposes the series into trend, seasonality, and holidays; it handles missing data, multiple seasonalities, and non-uniform time grids with minimal tuning and is accessible to non-statisticians. ARIMA is a statistical model based on autocorrelation structure; it is more appropriate when the series is short, noise is small, and you need principled uncertainty intervals from an explicit stochastic process.

What are trend, seasonality, and residual in time series decomposition, and how do you extract them?

Decomposition separates a series into a trend component (long-run direction), a seasonal component (periodic, fixed-period pattern), and a residual (everything left over). Additive decomposition sums the three; multiplicative decomposition multiplies them, which is appropriate when seasonal swings grow with the level.

What is the difference between ARIMA and SARIMA, and when do you use each?

ARIMA(p,d,q) models non-seasonal series by combining autoregression, differencing, and a moving average of errors. SARIMA extends it with a second set of seasonal parameters (P,D,Q,s) that operate at the seasonal lag s, handling periodic patterns that ARIMA alone cannot capture.

Related lessons

Explore further

Skip to content