🎉 75% of content is free forever — Unlock Premium from $10/mo →
CW
Search courses…
💼 Servicesℹ️ About✉️ ContactView Pricing Plansfrom $10

Seasonal Decomposition — STL and Classical

StatisticsTime Series Analysis🟢 Free Lesson

Advertisement

Seasonal Decomposition — STL and Classical

Statistics

Separating Trend, Seasonality, and Residual Components

Seasonal decomposition breaks a time series into interpretable components — underlying trend, repeating seasonal patterns, and random noise. STL and classical methods each offer advantages for different data characteristics.

  • Retail Planning — Isolate holiday shopping trends from underlying growth

  • Energy Forecasting — Separate daily and weekly cycles from long-term demand shifts

  • Healthcare — Detect flu season patterns from baseline hospital admission trends

Understanding the parts makes the whole pattern clear.


Seasonal decomposition separates a time series into trend, seasonal, and residual components, making patterns easier to identify and model.

DfAdditive Decomposition

A time series can be decomposed as:

Additive Model

Yt=Tt+St+RtY_t = T_t + S_t + R_t

Here,

  • YtY_t=Observed value at time t
  • TtT_t=Trend component
  • StS_t=Seasonal component
  • RtR_t=Residual (remainder) component

DfMultiplicative Decomposition

When seasonal variation changes with the level of the series:

Multiplicative Model

Yt=Tt×St×RtY_t = T_t \times S_t \times R_t

Here,

  • TtT_t=Trend component
  • StS_t=Seasonal component (proportion)
  • RtR_t=Residual component

Choosing Model Type

Use the additive model when seasonal fluctuations are constant. Use the multiplicative model when seasonal fluctuations increase with the level of the series. The log transform converts multiplicative to additive.


Classical Decomposition

Moving Average Method

For additive decomposition with period ss:

Centered Moving Average

MAt=1sj=(s1)/2(s1)/2Yt+jMA_t = \frac{1}{s}\sum_{j=-(s-1)/2}^{(s-1)/2} Y_{t+j}

Here,

  • ss=Seasonal period (e.g., 12 for monthly data)

Steps:

  1. Compute the centered moving average to estimate TtT_t

  2. Detrend: YtTtY_t - T_t (additive) or Yt/TtY_t / T_t (multiplicative)

  3. Average detrended values by season to get StS_t

  4. Residual: Rt=YtTtStR_t = Y_t - T_t - S_t

Classical Method Limitations

Classical decomposition assumes the seasonal pattern is fixed and does not adapt to changes. It also loses endpoints (first and last observations). For modern data, prefer STL.


STL Decomposition

Seasonal and Trend decomposition using Loess (Cleveland et al., 1990) is a more robust and flexible method.

DfSTL Algorithm

STL iteratively applies Loess smoothing (local regression) to estimate trend and seasonal components. It handles any seasonal period and is robust to outliers.

STL Advantages

| Feature | Classical | STL |

|---------|-----------|-----|

| Handles any period | No (fixed s) | Yes |

| Robust to outliers | No | Yes |

| Seasonal pattern adapts | No | Yes |

| Handles missing data | Limited | Yes |

| Computational speed | Fast | Moderate |


Strength of Seasonal Component

The strength of the seasonal component measures how much of the variation is due to seasonality.

Seasonal Strength

Fs=1Var(Rt)Var(St+Rt)F_s = 1 - \frac{\text{Var}(R_t)}{\text{Var}(S_t + R_t)}

Here,

  • FsF_s=Seasonal strength (0 to 1)
  • RtR_t=Residual component
  • StS_t=Seasonal component

| Value | Interpretation |

|-------|---------------|

| 0.6 - 1.0 | Strong seasonality |

| 0.3 - 0.6 | Moderate seasonality |

| 0.0 - 0.3 | Weak seasonality |


Python Implementation


import numpy as np

import pandas as pd

import matplotlib.pyplot as plt

from statsmodels.tsa.seasonal import seasonal_decompose, STL



# Simulate monthly data with trend and seasonality

np.random.seed(42)

n = 240

t = np.arange(n)

trend = 100 + 0.5 * t

seasonal = 10 * np.sin(2 * np.pi * t / 12)

noise = np.random.randn(n) * 2

y = trend + seasonal + noise



dates = pd.date_range('2005', periods=n, freq='M')

ts = pd.Series(y, index=dates)



# Classical decomposition

result_classical = seasonal_decompose(ts, model='additive', period=12)



# STL decomposition

stl = STL(ts, period=12, robust=True)

result_stl = stl.fit()



# Plot comparison

fig, axes = plt.subplots(4, 2, figsize=(14, 10))

for i, (comp, label) in enumerate(zip(['observed','trend','seasonal','resid'],

                                        ['Observed','Trend','Seasonal','Residual'])):

    axes[i, 0].plot(result_classical.observed if comp=='observed'

                     else getattr(result_classical, comp))

    axes[i, 0].set_title(f'Classical - {label}')

    axes[i, 1].plot(result_stl.observed if comp=='observed'

                     else getattr(result_stl, comp))

    axes[i, 1].set_title(f'STL - {label}')

plt.tight_layout()

plt.show()



# Seasonal strength

var_resid = np.var(result_stl.resid)

var_season_resid = np.var(result_stl.seasonal + result_stl.resid)

F_s = 1 - var_resid / var_season_resid

print(f"Seasonal Strength: {F_s:.3f}")

Worked Example

Example: Airline Passengers

Monthly airline passenger data (1949-1960) shows:

  • Increasing trend from 100 to 500+ passengers

  • Multiplicative seasonality — amplitude grows with level

  • Period: 12 months

Steps:

  1. Apply log transform: Zt=ln(Yt)Z_t = \ln(Y_t) to convert multiplicative to additive

  2. Run STL with period = 12

  3. Trend: Smooth upward curve from 4.6 to 6.2 (log scale)

  4. Seasonal: Regular pattern oscillating around 0

  5. Residual: Random noise, no remaining patterns

  6. Seasonal strength: Fs=0.87F_s = 0.87 -> strong seasonality


Key Takeaways

Summary: Seasonal Decomposition

  • Decompose series into trend TtT_t, seasonal StS_t, and residual RtR_t

  • Additive model: Yt=Tt+St+RtY_t = T_t + S_t + R_t (constant seasonal variation)

  • Multiplicative model: Yt=Tt×St×RtY_t = T_t \times S_t \times R_t (growing variation)

  • STL is preferred: handles any period, robust to outliers, adaptive

  • Seasonal strength FsF_s quantifies how seasonal the data is

  • Use decomposition to check if residuals look like white noise


Related Topics

Premium Content

Seasonal Decomposition — STL and Classical

Unlock this lesson and 900+ advanced tutorials with a Premium plan.

🎯End-to-end Projects
💼Interview Prep
📜Certificates
🤝Community Access

Already a member? Log in

Need Expert Statistics Help?

Get personalized tutoring, project support, or professional consulting.

Advertisement