Seasonal Decomposition of Time Series (STL, Classical Decomposition)
1. Introduction to Seasonal Decomposition
Seasonal Decomposition of Time Series (SDTS) is a statistical technique used to break down a time series into its fundamental components:
- Trend (T) – The long-term movement in the data.
- Seasonality (S) – Periodic fluctuations that occur at regular intervals (e.g., daily, monthly, yearly).
- Residual/Irregular Component (R) – The random noise or unexplained variations in the data.
This decomposition helps in analyzing patterns and making forecasts.
2. Why Use Seasonal Decomposition?
✅ Identifies trends and seasonal patterns in data.
✅ Removes seasonality for better forecasting.
✅ Enhances model interpretability.
✅ Useful for pre-processing time series data before applying forecasting models (like ARIMA, Exponential Smoothing, LSTMs).
3. Types of Seasonal Decomposition Methods
There are two main approaches:
1️⃣ Classical Additive and Multiplicative Decomposition
2️⃣ STL Decomposition (Seasonal-Trend Decomposition using LOESS)
4. Classical Seasonal Decomposition (Additive & Multiplicative Models)
4.1. Additive Model
Used when the seasonal fluctuations remain constant over time. Yt=Tt+St+RtY_t = T_t + S_t + R_t
- Y_t = Observed time series value at time t.
- T_t = Trend component.
- S_t = Seasonal component.
- R_t = Residual component.
✅ Suitable for linear trends and fixed seasonal variations.
4.2. Multiplicative Model
Used when seasonal variations increase or decrease over time (non-constant seasonal fluctuations). Yt=Tt×St×RtY_t = T_t \times S_t \times R_t
✅ Suitable for exponential growth trends and changing seasonality effects.
📌 When to Use Which?
- Use Additive → If variations remain constant.
- Use Multiplicative → If variations increase/decrease over time.
5. Implementing Classical Seasonal Decomposition in Python
Step 1: Import Required Libraries
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from statsmodels.tsa.seasonal import seasonal_decompose
Step 2: Load and Visualize the Time Series Data
# Load dataset (ensure it has a datetime index)
df = pd.read_csv("time_series_data.csv", parse_dates=["Date"], index_col="Date")
# Plot the original data
plt.figure(figsize=(12,6))
plt.plot(df.index, df['Value'], label="Original Time Series", color='blue')
plt.xlabel("Time")
plt.ylabel("Value")
plt.title("Time Series Data")
plt.legend()
plt.show()
Step 3: Apply Seasonal Decomposition
# Perform decomposition
result = seasonal_decompose(df['Value'], model='multiplicative', period=12) # Change 'additive' if needed
# Plot the decomposed components
result.plot()
plt.show()
✅ The above code breaks down the time series into Trend, Seasonality, and Residual components.
6. STL Decomposition (Seasonal-Trend Decomposition using LOESS)
📌 Why Use STL?
STL (Seasonal and Trend decomposition using LOESS) is an advanced method that:
✔ Provides more flexible seasonality handling.
✔ Works well for non-stationary data.
✔ Handles missing data better than classical decomposition.
Step 1: Install Necessary Library
from statsmodels.tsa.seasonal import STL
Step 2: Apply STL Decomposition
stl = STL(df['Value'], seasonal=13) # Adjust seasonality period if needed
result_stl = stl.fit()
# Plot STL decomposition
fig = result_stl.plot()
plt.show()
✅ STL is more robust than classical decomposition and works well with complex seasonality.
7. Analyzing the Components
After decomposition, we get:
1️⃣ Trend Component
- Shows the underlying direction of the time series (upward or downward movement).
- Extracted using a moving average or smoothing function.
2️⃣ Seasonal Component
- Represents repeating patterns (e.g., daily, weekly, yearly).
- Helps detect recurring fluctuations in the data.
3️⃣ Residual Component
- Represents random noise in the data after removing trend and seasonality.
- If residuals appear random, the decomposition is good.
- If patterns remain, another model may be needed.
8. Model Selection Based on Decomposition
Once we analyze the components:
✅ If trend is strong → Use Holt’s Exponential Smoothing or ARIMA.
✅ If seasonality is strong → Use Holt-Winters, SARIMA, or Prophet.
✅ If residuals are high → Data may need further pre-processing.
9. Forecasting with Decomposed Components
Step 1: Extract Components for Forecasting
trend = result.trend
seasonal = result.seasonal
residual = result.resid
Step 2: Forecast Using Trend + Seasonality
future_trend = trend[-12:].mean() # Assuming trend is stable
future_seasonality = seasonal[-12:] # Assuming seasonality repeats
future_forecast = future_trend + future_seasonality
# Plot Forecast
plt.figure(figsize=(12,6))
plt.plot(df.index, df['Value'], label="Original Data")
plt.plot(pd.date_range(start=df.index[-1], periods=12, freq='M'), future_forecast, label="Forecast", color='red')
plt.legend()
plt.show()
✅ Combining trend and seasonality helps generate forecasts.