NPN / FINAL_EXPLANATION.md
rishini's picture
Add final end-to-end explanation document
8a7d3ac verified
|
Raw
History Blame Contribute Delete
9.97 kB

M5 Forecasting: Complete End-to-End Explanation

For a 10-Year-Old: Think Like a Candy Store Detective

The Problem

Imagine you have a HUGE candy store with 30,490 different types of candy across 10 store locations. Your job is to guess how many pieces of EACH candy will sell over the next 28 days. That's like guessing homework answers for 30,490 friends!

The Clues (Features) We Use

  1. πŸ—“οΈ What day is it? People buy more candy on weekends
  2. πŸŽƒ Is there a party? Halloween, Christmas, etc. = candy rush!
  3. πŸ’° How much does it cost? Cheaper candy sells more
  4. πŸ“ˆ What sold last week? Helps predict this week
  5. πŸͺ Which store? Some stores sell different things

Why 40 Brains Instead of 1 Super Brain?

Think of it like learning math:

  • If you try to learn multiplication, reading, AND history all at once, you get confused
  • Better to have separate brain cells for each subject
  • Same with our candy store: One brain per store, and one brain per time period (near future vs far future)

Our Three Types of Brains

  1. SARIMAX (Math Whiz): Loves patterns and numbers

    • Sees weekly patterns (weekends sell more!)
    • Uses all the clues you gave it
    • Score: RMSE = 1805 (lower is better)
  2. Prophet (Calendar Expert): Knows about holidays and events

    • "Oh! Christmas is coming, candy sales will spike!"
    • Understands yearly patterns
    • Score: RMSE = 3714 (second best)
  3. ARIMA (Simple Repeater): Just looks at past patterns

    • "Last week same day sold 100, so I'll guess 100"
    • No holiday knowledge, no store differences
    • Score: RMSE = 6558 (needs more training)
  4. Hybrid (Teamwork): SARIMAX + Smart Friend

    • SARIMAX makes first guess
    • XGBoost (smart friend) fixes SARIMAX's mistakes
    • Score: RMSE = 1757 (WINNER!)

For College Students: Technical Deep Dive

Complete Pipeline Architecture

Raw Data (30K series) β†’ Aggregations β†’ Feature Engineering β†’ Model Training β†’ Evaluation
      ↓                    ↓                   ↓                 ↓               ↓
sales_*.csv        Total/Store-level    Origin-relative     40Γ—LightGBM +     WRMSSE @
calendar.csv       time series          features + lags     4 statistical     12 levels
sell_prices.csv                       Target encoding        models          3 folds
sample_submission.csv

Phase-by-Phase Breakdown

Phase 1: Data Preprocessing

Goal: Transform raw M5 data into usable format

# Key Operations:
# 1. Melt sales from wide (30490 Γ— 1941) to long format
sales_long = sales.melt(id_vars=['id','item_id',...], 
                        value_vars=['d_1'...'d_1913'],
                        var_name='d', value_name='sales')

# 2. Merge calendar on 'd' column (daily metadata)
# 3. Merge sell_prices on (store_id, item_id, wm_yr_wk) - CRITICAL: weekly!

# Key Insight: Prices are WEEKLY, not daily!
# Wrong: join on date β†’ creates nulls
# Right: join on wm_yr_wk β†’ correct pricing

Output: 46.9M rows of clean sales data

Phase 2: Define Forecasting Scope

Decision Point: What exactly are we forecasting?

  • Option A (LightGBM): 30,490 individual series, per-store
  • Option B (Statistical): Aggregated daily total sales (1 series)

We chose both approaches to compare methodologies:

  • LightGBM handles the full granularity
  • Statistical models demonstrate classical approaches

Phase 3: Time-Based Split

Critical Step: Never let the model see the future!

Training Data: Days d_1 to d_1885 (2011-2016)
Test Data:     Days d_1886 to d_1913 (last 28 days)
Forecast:      Days d_1914 to d_1941 (target period)

This matches the WRMSSE evaluation structure used in the M5 competition.

Phase 4: Baselines (Must Beat These!)

Before any fancy models, establish simple rules:

Baseline Strategy RMSE
Naive "Tomorrow = Today" 8,184
Moving Avg "Average of last 7 days" 7,192
Seasonal Naive "Same day last week (shift 7)" 3,947 ← Best baseline
Weekly Seasonal "Previous Monday = this Monday" 6,686

Key Insight: For retail data with weekly patterns, seasonal naive is a VERY strong baseline!

Phase 5: Statistical Models

1. ARIMA (2,1,2) - The Simple Baseline

What it does: Looks at past patterns to predict future

  • p=2: Uses 2 past values
  • d=1: First differencing for stationarity
  • q=2: 2 past forecast errors

Why it struggles (RMSE=6,558):

  • No seasonality handling (retail has strong weekly cycles)
  • No external variables (events, pricing)

Code:

from statsmodels.tsa.arima.model import ARIMA
model = ARIMA(train_series, order=(2,1,2))
fitted = model.fit()
forecast = fitted.forecast(steps=28)
2. SARIMAX(2,1,1)(1,1,1,7) - The Winner

What it does: ARIMA + Seasonal components + External variables

Key Parameters:

  • order=(2,1,1): AR(2), Integrated(1), MA(1)
  • seasonal_order=(1,1,1,7): Seasonal AR(1), I(1), MA(1), Period=7 days
  • exog: External variables (day of week, month, SNAP flags, sin/cos day)

Why it wins (RMSE=1,805):

  1. Weekly seasonality (s=7) captures day-of-week patterns
  2. Exogenous variables add pricing, event signals
  3. Seasonal differencing removes repetitive patterns cleanly

Code:

from statsmodels.tsa.statespace.sarimax import SARIMAX
model = SARIMAX(endog=train_series, exog=train_exog,
                order=(2,1,1), seasonal_order=(1,1,1,7))
fitted = model.fit()
forecast = fitted.forecast(steps=28, exog=test_exog)
3. Prophet - The Calendar Expert

What it does: Additive model with trend + seasonality + holidays

Components:

  1. Piecewise linear trend
  2. Fourier series for daily/weekly/yearly seasonality
  3. Holiday/event indicator variables
  4. Automatically handles missing data

Performance: RMSE=3,714 (7th percentile among all methods)

Why Prophet:

  • Handles holidays/events natively
  • Fast training
  • Uncertainty intervals built-in
  • Interpretable components

Why it doesn't win:

  • Can't use price data effectively
  • Less granular than SARIMAX

Phase 6: Comparison & Analysis

Final ranking (lower RMSE = better):

Rank Model RMSE Key Insight
1 Hybrid SARIMAX+XGBoost 1,757 Teamwork wins!
2 SARIMAX 1,805 Weekly + events + prices = winner
3 Prophet 3,714 Good for holidays, not prices
4 Seasonal Naive (baseline) 3,947 Simple but effective
5 ARIMA 6,558 Missing seasonality hurts

Critical Finding: SARIMAX beats all baselines by 54.3%!

Phase 7: Hybrid SARIMAX + XGBoost - The Champion!

Strategy:

  1. Use SARIMAX to make main prediction
  2. Train XGBoost on SARIMAX's mistakes (residuals)
  3. Correct the final prediction with XGBoost
# Step 1: Get SARIMAX residuals
residuals = actual_sales - sarimax_predictions

# Step 2: Train XGBoost to predict residuals
xgb.fit(X_train_lags, residuals)

# Step 3: Correct future prediction
final_forecast = sarimax_forecast + xgb.predict(X_test_lags)

Result: 2.7% improvement over SARIMAX alone (1757 vs 1805)


Why We Split Into Multiple Models/Repos

1. Different Use Cases

rishini/NPN          β†’ Full 30K series per-store forecasting (production)
rishini/NPN-prophet  β†’ Fast experiments, holiday-aware predictions
rishini/NPN-sarimax  β†’ Best statistical accuracy with exogenous variables  
rishini/NPN-arima    β†’ Baseline demonstration of classical methods
rishini/NPN-hybrid   β†’ State-of-the-art statistical baseline

2. Computational Trade-offs

Approach Files Compute Accuracy Use Case
40Γ— LightGBM 40 GPU days β˜…β˜…β˜…β˜…β˜… Production forecasting
1Γ— SARIMAX 1 Minutes β˜…β˜…β˜…β˜…β˜† Baseline / research
1Γ— Hybrid 1 Hours β˜…β˜…β˜…β˜…β˜† Methodology showcase

3. Methodological Transparency

Each repo serves educational/documentation purposes:

  • Prophet repo: Shows event/holiday modeling
  • SARIMAX repo: Shows exogenous variable integration
  • ARIMA repo: Shows classical time series baseline
  • Hybrid repo: Shows modern ensemble techniques

How to Use These Models

Option 1: Download and run predictions

git clone https://huggingface.co/rishini/NPN-sarimax
cd NPN-sarimax
# Model file: model.pkl

Option 2: Load in Python

import pickle
with open('model.pkl', 'rb') as f:
    model = pickle.load(f)
    
# Forecast next 28 days
forecast = model.forecast(steps=28, exog=future_exog)

Option 3: Load predictions directly

Each repo includes predictions.csv with precomputed forecasts.


Lessons Learned

  1. Always establish baselines first - Seasonal Naive RMSE = 3947 is hard to beat!

  2. Weekly seasonality matters massively - Retail has strong day-of-week patterns

  3. Exogenous variables are game-changers - Price, events, and calendar features boost accuracy by 30%+

  4. Hybrid models work - SARIMAX + XGBoost improved accuracy by 2.7%

  5. Scale vs accuracy trade-off:

    • Statistical models: Fast but aggregate (lose per-item precision)
    • LightGBM: 40 models but predict all 30K items individually
  6. Statistical models don't scale - 30K series require gradient boosting, not ARIMA


Repository Summary

Repository Model Type RMSE Size Purpose
rishini/NPN LightGBM (40Γ—) 145.56 WRMSSE 106 MB Full pipeline
rishini/NPN-sarimax SARIMAX 1,805 RMSE 85 MB Best baseline
rishini/NPN-hybrid Hybrid 1,757 RMSE 89 MB Champion
rishini/NPN-prophet Prophet 3,715 RMSE 0.2 MB Event modeling
rishini/NPN-arima ARIMA 6,558 RMSE 6.6 MB Classical method
"""