Dominick's scanner data · pricing & promotion
Retail Promotion Decision Engine
A promotion analysis that asks whether a discount adds contribution margin rather than unit lift — and recommends no action when the evidence cannot support one.
The question
Which products should a retailer promote, at what discount, and in which stores, when the objective is incremental contribution margin rather than unit lift or revenue alone?
The data
University of Chicago Booth Kilts Center Dominick's Finer Foods scanner data, built into validated store-product-week panels with explicit checks on keys, prices, quantities, source quality, and bundle-price semantics. Promotion coding is incomplete, historical pricing was not randomized, and stockouts are not cleanly observed — limits that shape every conclusion below.
How it was done
- A validated DuckDB mart establishes store-product-week grain and provenance.
- Fixed-effects and hierarchical Bayesian models estimate conditional price response with temporal holdouts and partial pooling.
- A doubly robust promotion analysis faces overlap, balance, placebo, and negative-control tests before it can influence optimization.
- A mixed-integer optimizer compares revenue and contribution-margin scenarios under capacity and downside-risk constraints.
- Release gates block recommendations when causal identification, calibration, monitoring, or economic inputs are inadequate.
What the evidence showed
| Evidence | Result | Decision implication |
|---|---|---|
| Bayesian holdout uncertainty | 81.9% coverage for a nominal 90% interval | Model is overconfident |
| Split-conformal recalibration | 85.4% coverage on a later window | Improvement, still below target |
| Historical shadow replay | Twelve of thirteen weeks trigger at least one block | Aggregate performance hides unstable weeks |
| Strict propensity overlap | 29.1% of rows | Historical promotion effect is not decision-grade |
| Post-weighting balance | Maximum absolute SMD 0.224 | Residual imbalance remains material |
| Revenue scenario | +$1,159 revenue and −$481 contribution margin | Unit and revenue lift do not imply profitability |
| Downside-screened margin scenario | Zero actions at all tested capacities | No promotion is the robust base-case decision |
What I recommend
- Do not deploy the observational promotion estimate or use it to automate promotion selection. The large adjusted effect is withheld because overlap, balance, a future-treatment placebo, and a past-outcome negative control all fail. Numerical convergence does not override failed identification.
- Keep the engine as a refusal mechanism and experiment-design tool: it names the missing evidence, stops an invalid causal estimate from reaching the optimizer, and keeps "no action" on the table when margin risk is unfavorable.
- Run a stratified randomized promotion test next — explicit discount depths, stratified by store, product and baseline velocity, with unit sales and incremental contribution margin pre-registered as co-primary outcomes. Capture display and feature status, offered price on zero-sales weeks, inventory and stockouts, supplier funding, and current replacement cost.
- Supplier funding is the commercial lever to negotiate: no candidate clears the downside screen unfunded, while $0.10 per promoted unit allows 12 modeled actions with roughly $14 aggregate funded margin. A planning calculation for 20% unit lift over 13 weeks at intraclass correlation 0.05 needs about 43 stores per arm.
What this does not prove
- Price-response coefficients are conditional associations, not causal elasticities.
- The recorded promotion flag is incomplete, and unlabeled weeks are not proven controls.
- The demand model conditions on positive sales and cannot identify censored demand or stockouts.
- Optimizer economics use historical accounting-cost proxies, not a current replacement-cost feed.
- Substitution, basket effects, residual demand shocks, and future regime changes sit outside the scenario model.
- A containerized, monitored service is not evidence that the policy is safe to deploy.