PRICING ML
ClearanceAI
A markdown price optimizer that sets regional markdowns twice a month by combining demand elasticity models with stock age heuristics.
- Python
- PySpark
- Delta Lake
- MLflow
- demand elasticity modeling
- FastAPI
- Kubernetes
Context
Markdown timing and depth were set by heuristics that did not account for regional demand differences or how long stock had been sitting.
A markdown that is too shallow leaves inventory in the building, and one that is too deep gives away margin on units that would have sold anyway. Both failures are invisible unless the regions are compared against each other.
Constraints
Markdowns are a scheduled business process, not a live auction. The model had to produce a defensible recommendation on a bi-monthly cadence rather than react continuously.
Regional demand differences are the whole point, so a single national elasticity curve would have reproduced the problem the system was built to fix.
Downstream systems consume price feeds, so the output had to be a stream the merchandising APIs could take, not a report someone re-keys.
What I built
Elasticity models per product family combined with stock age heuristics, producing regional markdown recommendations on a bi-monthly cadence, streamed as dynamic price feeds.
The MLOps stack underneath it: training, registry promotion, serving and monitoring, on the same standard as the rest of the pricing platform.
Architecture
Demand elasticity is estimated per product family from Delta Lake history with PySpark, so the unit of the model matches the unit merchandising actually reasons about.
Stock age enters as a heuristic layer over the elasticity estimate rather than as another feature, which keeps the markdown recommendation explainable to the people signing off on it.
Models are versioned in MLflow and served behind FastAPI on Kubernetes, and the recommendations leave as dynamic price feeds to the merchandising APIs.
Results
Sell-through lifted 4.6 percent.
Regional markdowns now set twice a month from the model rather than from a flat heuristic.
Dynamic price feeds stream to the merchandising APIs on the same cadence.
What I would do differently
Build the regional holdout structure into the first release rather than retrofitting it, since clean regional controls are what made the sell-through number defensible.
The measurement design is part of the product. Retrofitting it cost a cycle and made the early results harder to argue for than they needed to be.