🎉 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.


Classical Decomposition

Moving Average Method

For additive decomposition with period :

Steps:

  1. Compute the centered moving average to estimate

  2. Detrend: (additive) or (multiplicative)

  3. Average detrended values by season to get

  4. Residual:


STL Decomposition

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

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.

| 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


Key Takeaways


Related Topics

Need Expert Statistics Help?

Get personalized tutoring, project support, or professional consulting.

Advertisement