← Back to projects

Case study

Demand Forecasting System

Supply-chain demand forecasts with LightGBM and XGBoost, plus a published naive-baseline benchmark.

At a glance

Plain summary for recruiters and visitors. Technical detail follows below.

What it is
I built a supply chain demand forecasting pipeline with tree models and simple baselines. On a fixed benchmark series it slightly beats a naive mean forecast.
What I owned
Solo end to end. Lag features, LightGBM and XGBoost training, baseline benchmarks, optional agentic model pick, and the portfolio forecast demo.
Why it matters
Even a small edge over naive mean can reduce waste when the same logic runs across many SKUs. The case study reports honest one-step numbers before any multi-step serving claim.
Try it on this page vs full project
The chart demo uses lightweight JavaScript models on curated series. The published about 26% MAPE table comes from the full XGBoost and LightGBM stack on request.
Demand Forecasting System

Problem

Supply chain teams waste time on manual forecasts that miss demand swings and inflate inventory cost.

Method

Combined lag features with LightGBM and XGBoost, plus classical baselines and an agentic mode for model selection. Benchmarked one-step skill against naive mean and seasonal naive on a fixed seed.

Result

About 26% MAPE one-step (XGBoost) on the published synthetic protocol, slightly ahead of naive mean. Multi-step recursive serving is reported separately so limits stay clear.

Architecture

How the system is shaped. Full implementation stays private.

  1. Step 1

    Ingest

    Time series demand feeds with validation and scale checks.

  2. Step 2

    Features

    Lags, calendar effects, and rolling stats for tree models.

  3. Step 3

    Models

    LightGBM, XGBoost, classical baselines, optional agentic model pick.

  4. Step 4

    Evaluate

    MAPE/WAPE versus naive mean and seasonal naive on a fixed seed before serving.

One-step MAPE vs baselines

Fixed synthetic seed 42, 730 days, 80/20 split, first 30 test days, teacher-forced lags. Multi-step recursive forecasts are weaker for trees on this series. The published table is one-step MAPE only.

ModelMAPENote
XGBoost26.2%Best in this run
Naive mean26.9%
LightGBM30.7%
Seasonal naive (p=7)119.1%

Algorithm

Gradient-boosted demand regression

Tabular time-series features into LightGBM/XGBoost with optional ensemble blending and agentic model choice.

X, y = build_lag_features(series)
model = LightGBM.fit(X_train, y_train)
yhat = model.predict(X_test)
mape = mean(abs(y_test - yhat) / y_test)
compare(mape, naive_mean_mape, seasonal_naive_mape)

Key logic

Compact illustrative snippet (Lag and calendar features (illustrative)). Not the full codebase.

def build_lag_features(series, lags=(1, 7, 14), rolls=(7, 28)):
    df = pd.DataFrame({"y": series})
    for k in lags:
        df[f"lag_{k}"] = df["y"].shift(k)
    for w in rolls:
        df[f"roll_mean_{w}"] = df["y"].rolling(w).mean()
    df["dow"] = df.index.dayofweek
    df["month"] = df.index.month
    return df.dropna()

Stack

Time Series ForecastingLightGBMXGBoostMachine LearningAgentic AIHyperparameter TuningSupply Chain AnalyticsPython

Try a live forecast

Free Cloudflare demo on a curated series. Pure JS seasonal, Holt, and lag-ridge only. The published case-study table is one-step XGBoost at about 26% MAPE on a different synthetic protocol.

Scenario

Model

Source code

Full source is available to hiring managers on request. The public page shows architecture, algorithms, and compact proofs only.