Model-selection decision tree
Choose a demand estimator first; a separate constrained optimiser picks among approved prices. “Logs ready?” means usable demand, price exposure, cost and inventory histories. “Effect + support?” needs defensible identification and observations near the candidate prices, not a good forecasting score. For identified, uncensored demand, fit the GLM baseline before judging whether its remaining errors justify a more flexible challenger.
1. Check data, evidence and inventory readiness
Diagram source
%%{init: {"theme":"base","themeVariables":{"fontFamily":"Arial, sans-serif","fontSize":"16px","textColor":"#17324D","primaryColor":"#F5F7FA","primaryTextColor":"#17324D","primaryBorderColor":"#8796A8","lineColor":"#718096","secondaryColor":"#EFF6FF","tertiaryColor":"#E9F6F2","clusterBkg":"#F8FAFC","clusterBorder":"#D6DEE8","edgeLabelBackground":"#FFFFFF"},"flowchart":{"htmlLabels":true,"nodeSpacing":18,"rankSpacing":28,"curve":"linear","padding":10,"subGraphTitleMargin":{"top":8,"bottom":12}}}}%%
flowchart TB
accTitle: Check readiness for price-response modeling
accDescr: Repair missing logs, retain forecasting when causal support is absent, and separate inventory extensions before continuing to the GLM baseline.
R{"Logs<br/>ready?"}
I{"Effect +<br/>support?"}
S{"Stock<br/>issues?"}
A["A<br/>Repair<br/>logs"]
B["B<br/>Forecast<br/>only"]
C["C<br/>Inventory<br/>extension"]
G["Fit GLM<br/>Next tree"]
R -->|No| A
R -->|Yes| I
I -->|Yes| S
I -->|No| B
S -->|Yes| C
S -->|No| G
classDef data fill:#EFF6FF,stroke:#3973AC,color:#17324D,stroke-width:1.5px
classDef model fill:#EFF2FD,stroke:#596FC2,color:#17324D,stroke-width:1.5px
classDef decision fill:#FFF5DF,stroke:#A8751A,color:#17324D,stroke-width:1.5px
classDef execution fill:#E9F6F2,stroke:#23866E,color:#17324D,stroke-width:1.5px
classDef neutral fill:#F5F7FA,stroke:#8796A8,color:#17324D,stroke-width:1.5px
class R,I,S decision
class A data
class B neutral
class C,G modelThe letters link each outcome to its requirements below. “Stock issues?” covers sales censored by stockouts and decisions tied to future inventory or replenishment, which need a separate extension. Having a model does not authorise a new price, and more rows cannot repair missing identification or price support. The “Fit GLM” path continues in the promotion tree below.
2. Decide whether the GLM needs a challenger
Follow this tree after the readiness checks above. Fit the GLM first, then use forward error analysis to decide whether a boosted comparison is worth running. Choosing a challenger does not show it beats the baseline.
Diagram source
%%{init: {"theme":"base","themeVariables":{"fontFamily":"Arial, sans-serif","fontSize":"16px","textColor":"#17324D","primaryColor":"#F5F7FA","primaryTextColor":"#17324D","primaryBorderColor":"#8796A8","lineColor":"#718096","secondaryColor":"#EFF6FF","tertiaryColor":"#E9F6F2","clusterBkg":"#F8FAFC","clusterBorder":"#D6DEE8","edgeLabelBackground":"#FFFFFF"},"flowchart":{"htmlLabels":true,"nodeSpacing":18,"rankSpacing":28,"curve":"linear","padding":10,"subGraphTitleMargin":{"top":8,"bottom":12}}}}%%
flowchart TB
accTitle: Compare a boosted demand challenger with the GLM
accDescr: Retain the interpretable GLM unless nonlinear errors justify comparing a boosted demand challenger on forward validation.
G["Fit log-price GLM"]
N{"GLM errors<br/>nonlinear?"}
D["D<br/>Keep GLM"]
E["E<br/>Boosted<br/>challenger"]
G --> N
N -->|No| D
N -->|Yes| E
classDef data fill:#EFF6FF,stroke:#3973AC,color:#17324D,stroke-width:1.5px
classDef model fill:#EFF2FD,stroke:#596FC2,color:#17324D,stroke-width:1.5px
classDef decision fill:#FFF5DF,stroke:#A8751A,color:#17324D,stroke-width:1.5px
classDef execution fill:#E9F6F2,stroke:#23866E,color:#17324D,stroke-width:1.5px
classDef neutral fill:#F5F7FA,stroke:#8796A8,color:#17324D,stroke-width:1.5px
class G,D,E model
class N decision- A · Repair the logs; keep the current approved policy. Model: no new price-response model yet. Missing exposures, costs or inventory make the decision target unreliable. Required: posted prices, exposed opportunities including non-purchases, timestamped costs and stock/availability. Proceed when reconciliation and readiness checks pass, and forecast only what the records support. See the data contract.
- B · Forecast only; gather intervention evidence. Model: a seasonal/count demand forecast, keeping the current approved pricing policy. Forecasting history cannot identify demand under a price change. Required for promotion: a bounded, approved price experiment or another defensible identification design, with local support for the proposed grid. Promote only within that identified, supported price region. See price-effect identification and the experiment design.
- C · Add a censored-demand/inventory extension only when supported. Model: a justified latent-demand distribution, with censor-aware estimation when sales are censored, plus a separate inventory optimisation model when decisions interact over time. Realised sales alone cannot reveal demand above available stock. Required: stock and availability histories, exposure, price/cost state, identifiable price effects and a validated observation/censoring model. Dynamic decisions also need replenishment and transition evidence. Promote after validating the observation model and demand-distribution calibration under the inventory rules; otherwise abstain from the unsupported price change. See the stock-censored research and simulator extension.
- D · Start with a regularised log-price Poisson or negative-binomial GLM. It gives an interpretable count-demand baseline, handles zero counts and can model exposure explicitly. Required: repeated product-market observations, valid exposure denominators, uncensored demand for this baseline, credible supported price variation and documented identification assumptions. Check forward performance, dispersion and uncertainty. See the elasticity baseline.
- E · Compare CatBoost or LightGBM with that GLM. Rich features and nonlinear seasonal/product interactions can justify a flexible demand challenger. Required: the same identified price evidence and support, features available at decision time, and a held-out forward comparison of accuracy, calibration, response curves and operating cost. Keep the GLM if the challenger adds nothing useful. See the boosted demand challenger.
Only a supported demand response moves on to the constrained price policy. There, feasibility, predictive risk and selection-adjusted improvement gate every candidate before selection. This tree organises the existing project work. Inventory and other advanced extensions stay outside its 25-hour practice budget.
| Evidence and data regime | Suggested model or approach | Gate before using it for decisions |
|---|---|---|
| Little price variation or incomplete logs | Current approved price; category rules; forecasting only | Instrument the missing exposures and assignment process |
| Repeated product-market observations with credible price variation | Regularised log-price Poisson/negative-binomial GLM, with SKU/store/calendar effects | Plausible elasticity, adequate support and defensible identification |
| Rich tabular features and nonlinear seasonal/product interactions | CatBoost or LightGBM demand model | Beats GLM on forward data; response curves and uncertainty remain credible |
| Sparse products or new SKUs | Hierarchical/partially pooled category elasticity plus item attributes | Category transfer validated on held-out products; conservative fallback |
| Identified heterogeneous price effects | DML or causal forest with a specified treatment-response model | Identification, residual price variation, cross-fitting and inference assumptions checked |
| Strong substitutions and assortment changes | Discrete-choice model, such as multinomial/nested logit, or a justified joint demand model | Choice set, outside option, availability and cross-price effects observed |
| Repeated decisions with approved exploration | Contextual bandit on a finite approved price grid | Correct propensities, matured reward, limited loss budget and operational stop rules |
These promotion gates are engineering recommendations. Model documentation sets out supported losses and estimator assumptions, not which model wins on your data.
The elasticity baseline
For counts, fit the conditional mean instead of taking the log of observed zero sales:
log E[units | p, x] = log(exposure)
+ item_effect + store_effect + calendar_effect
+ beta × log(p) + other_pre_decision_featuresHere beta is the elasticity of the conditional mean: a 1% price increase goes with roughly a
beta% change in demand, holding the modelled features fixed. An estimate of -1.4 suggests about
a 1.4% decrease. It is a causal elasticity only under the identification assumptions in the next
section.
A Poisson log-link handles zero counts naturally. Check for overdispersion (variance above the
mean); a negative-binomial model may fit it better. Use partial pooling or regularisation when many
products have little price variation. If you fit log-log regression on positive sales instead, state
that zeros are excluded and handle retransformation bias. log1p(units) loses the usual elasticity
meaning.
statsmodels documents the GLM families and links.
Check how your implementation handles dispersion. In statsmodels' negative-binomial GLM family, you
supply alpha; choosing the family does not estimate it. Estimate or tune dispersion on training
data with a suitable count model, then check the tails on held-out data. The
family documentation
states this contract.
The boosted demand challenger
CatBoost is a useful challenger when product, store and category identifiers matter most. LightGBM suits larger tabular panels. Both support Poisson and quantile objectives, as the CatBoost loss documentation and LightGBM parameters show. Choose by careful validation and operating needs, not a generic leaderboard.
Use a count loss for units. For zero-heavy, nonnegative continuous spending, compare a Tweedie or two-part model where suitable. A hurdle model can separate whether someone buys from how many units, but the extra complexity needs validation. Keep the response scale explicit: a library may return a raw log score or a transformed mean, depending on prediction settings.
Inspect demand curves across the supported price grid in real customer-market contexts. A monotonic constraint (demand falls as price rises) can encode a reasonable own-price assumption, but it cannot fix confounding. Check that your objective supports that constraint in the pinned library version. Flexible trees extrapolate poorly beyond observed prices, and a smooth curve does not prove a price change will work.
A boosted Poisson-loss model estimates a conditional mean. That objective alone does not validate a Poisson demand distribution, and a few fitted quantiles are not a complete distribution either. For inventory or downside-risk calculations, supply a coherent nonnegative demand distribution or a justified tail estimator, and validate dispersion, tail calibration and interval ordering. Keep uncertainty in the fitted mean separate from future demand variation.
When advanced models earn their place
For strong substitutes, estimate category demand and the no-purchase outside option, instead of maximising each SKU's apparent profit separately. A choice model's assumptions and feasibility matter as much as its fit. Personalised individual pricing is a separate product-policy decision that a pooled product-market demand model does not need.
Use a bandit only when exploration has been approved for the defined market and price grid. Start with a randomised fixed-grid experiment. Later, a contextual bandit can give more exposure to promising allowed prices while still exploring. Log the chosen action's real probability after all filters, inventory checks and policy constraints. The Vowpal Wabbit tutorial explains the context/action/reward/probability contract. A bandit optimising immediate purchases can lose money after discounts, returns or longer-term effects, so define a matured contribution reward.
Delayed feedback changes the learning contract. Declare a fixed return/settlement horizon and an allowance for late data. Keep recent decisions pending instead of giving them zero reward or updating only on quick outcomes. A whole decision cohort matures under one rule, and its reward may still miss later returns, so state that limit. Delays or missing outcomes can depend on price and reward. The peer-reviewed ICML study of unrestricted delay distributions separates reward-independent from reward-dependent delays, and ordinary bandit updates are not automatically valid in both. Start with scheduled updates on mature cohorts and an incumbent fallback. More elaborate delay-aware learning is an optional extension.
For a faster purchase or revenue proxy, individual-level correlation with settled profit is not enough. Check, with uncertainty, whether the randomised price effects on the proxy point the same way as those on matured contribution. The August 2026 delayed-feedback workshop paper by Lee and colleagues examines reward alignment and learning efficiency separately. Its marketplace example is underpowered, later overall lift is null and positive subgroup findings are exploratory, so it does not validate a retail pricing reward. Compare against an approved fixed-price policy, and confirm any proxy-driven policy with experimental settled-profit outcomes.
Optional depth: what the 2026 research adds
Continuous-treatment models and stock-censored demand research
Pretrained continuous-treatment models. The May 2026 CCPFN preprint, revised in July, studies in-context dose-response estimation using synthetic causal-model priors. It is an optional challenger for an identified price-response task, not a way to extract causal elasticity from any sales history. It needs the relevant confounders and local treatment support, and its benchmarks are mostly synthetic or semi-synthetic. Compare it with the GLM and a cross-fitted causal baseline on the same supported price region, future cohorts, response uncertainty and inference cost. Test prior mismatch explicitly. A smooth curve does not mean it learned the effect of prices that were never in the experiment.
Learning with stock-censored demand. Zhang, Wang and Luo's September 2026 preprint develops Double-Grid-UCB and Threshold-UCB for stationary bounded demand, nonincreasing expected sales with price at each inventory cap, and inventory known before pricing. Threshold-UCB shares demand-tail information across inventory levels. Its support is theory and simulations; seasonal drift, substitution, replenishment decisions and live profit gains need separate work.
Adaptive prices and inventory can also break ordinary i.i.d. Kaplan–Meier confidence arguments, so the paper builds estimates for its own observation process. A censoring flag alone cannot justify a survival estimator's uncertainty.
The practical lesson holds even with a GLM: log available stock, keep sales separate from latent demand, and estimate a demand distribution when stock limits the decision. Two made-up demand processes both have mean 10. One always sells 10 if available. The other has demand 0 or 20, each with probability one half. With inventory 10, expected served demand is 10 and 5 respectively. A mean-only forecast cannot tell their stock-limited contribution apart.
For nonnegative integer demand and integer inventory, the identity is:
E[min(D, I) | price, context] = sum from q=1 to I of P(D >= q | price, context)In a simulator, a finite-inventory extension can compare a naive sales-as-demand fit, a justified censored-demand model and an inventory-aware exploration policy. Vary stockouts and demand drift. Adapting its revenue objective to contribution is new work, and the regret guarantee does not carry over automatically. These optional extensions need an exploration and loss budget before live use.