Optimizing Markdown Timing
in Fast Fashion
A predictive approach to inventory clearance for $5M–$500M fast fashion retailers.
Built end-to-end as a full case study with production-ready artifacts — model, feature list, imputer, and scoring functions.
Fast fashion demand
is hard to predict.
Products launch, peak, and fade quickly. Many SKUs have long stretches of zero sales, and classical forecasting tools break under these conditions.
Models like SARIMA and Prophet expect smooth demand curves. Fast fashion does not have them. Naive lag models also fail because they treat stock-outs as real demand drops.
The business needed a forecasting system that could handle zero-inflated demand, understand lifecycle position, react to short-term momentum, avoid leakage from future markdowns, and support weekly buyer decisions.
XGBoost with a Tweedie objective solved all five requirements. It handles zero-inflation natively, learns lifecycle patterns from structured features, and respects strict pre-markdown cutoffs.
Clear insights that change
how markdown decisions get made.
Lifecycle position beats price history
The strongest signal was days_since_launch. Fast fashion follows a simple arc: launch, peak, decay. Knowing where a SKU sits in that arc predicts demand better than past sales or discount history.
Business impactBuyers can forecast demand for new SKUs earlier and with more confidence.
Recent momentum matters more than long history
Short windows (7-day averages and 7-day lags) captured real momentum. Older history added noise.
Business impactWeekly review cycles match the natural rhythm of demand.
Mid-range discounts are unpredictable
Demand at 21 to 40 percent discounts was unstable. Deep discounts and no discounts were predictable, but mid-range markdowns were not.
Business impactMove faster through mid-range discounts. Deep or no discount is stable, 21 to 40 percent is not.
Weighted MAE matches real financial risk
Standard MAE treats all SKUs the same. Weighted MAE penalizes errors on high-value items more.
Business impactThe metric now reflects margin risk, not just average error.
The model enables earlier decisions
Forecasting demand before markdowns lets buyers simulate wait-one-more-week scenarios.
Business impactMarkdown timing becomes proactive instead of reactive.
Turning the model
into decisions.
Mark down based on lifecycle position, not gut feel
Use the model's lifecycle signal to decide when to act. Early-lifecycle SKUs should wait. Late-lifecycle SKUs should move faster.
Business impactHigher margin capture and fewer premature markdowns.
Avoid mid-range discounts
21 to 40 percent discounts produce unstable demand. Move quickly through this zone or skip it entirely and go straight to deep discounts.
Business impactMore predictable sell-through and fewer stuck SKUs.
Simulate before you mark down
Run the model before applying any discount. If demand is forecast to fall next week, mark down now. If it is stable, wait.
Business impactMarkdown timing becomes proactive instead of reactive.
Before vs. After
The choices that
made the model useful.
Lifecycle Position
This feature let the model forecast demand for new SKUs before any sales history existed. Technically: days_since_launch captured the launch, peak, decay arc in one number.
Velocity Signals
Short windows (rolling 7-day average and 7-day lag) showed real momentum. Technically: longer lags added noise because most SKUs do not live that long.
XGBoost + Tweedie Objective
This combination handled zero-inflated demand directly. Technically: it avoided the need for a two-stage hurdle model.
Leakage-Safe Feature Windows
This kept the model honest. Technically: all features were built from data available before the prediction day.
Weighted MAE
This aligned evaluation with margin risk. Technically: high-value SKUs carried more weight in the error metric.
The honest version
of building this.
Long Lag Features
14-day and 21-day lags added noise. Most SKUs do not have clean history that long. Fix: restricted lags to 7-day windows.
Mid-Range Discount Volatility
The model struggled with 21 to 40 percent discounts. This is a real buyer behavior pattern, not a model flaw. Fix: treated mid-range discounts as high-variance zones.
Early Feature Leakage
Some early features accidentally used post-markdown information. Fix: rebuilt the pipeline with strict pre-prediction cutoffs.
Unnecessary External Features
Social sentiment and web trends added noise and did not match weekly cycles. Fix: removed them. Lifecycle plus velocity carried the signal.
How it was built,
and how it was measured.
Model Stack
XGBoost (Tweedie objective)
Gradient boosting tuned for zero-inflated retail demand.
Scikit-learn pipeline
End-to-end feature transforms wired into a single reproducible pipeline.
SHAP for interpretability
Per-prediction attribution so buyers can see why a forecast moved.
Gain-based feature importance
Global ranking used to prune noisy inputs during iteration.
SKU-level train/test split
Held-out SKUs (not just held-out weeks) to test true cold-start behavior.
Evaluation
Weighted MAE
Primary metric. Penalizes errors on high-value SKUs more than cheap clearance items.
Quantile loss
Uncertainty bounds so under-forecasts on hot sellers show up clearly.
SKU-level holdout
Prevents leakage across the train/test boundary.
SHAP values
Readable explanations for buyers, not just model developers.
Why synthetic data
was the right choice.
A carefully engineered synthetic dataset designed to mimic real fast fashion behavior.
Zero-inflated sales, lifecycle curves, markdown events, seasonal patterns, cold-start SKUs, stockout noise, and discount volatility. Every failure mode a live retail pipeline would face was represented on purpose.
Synthetic data allowed full control over edge cases without relying on proprietary retail data. Building and validating the data environment was part of the work, a core skill for decision intelligence systems that need to test edge cases safely.
Predictive-Markdown-Intelligence
Complete end-to-end ML system for retail demand forecasting.