A category team decides the shelf has too many similar products. Pruning the assortment sounds rational: remove low-velocity SKUs, free shelf space, reduce working capital, and simplify the customer choice. The problem is that products live in baskets, not spreadsheets.
Share: Assortment optimization is not just pruning slow SKUs. Substitutes, complements, shelf space, inventory, and basket economics decide what actually happens. #Causality #RetailAnalytics #Assortment
Synthetic teaching model
This article uses a synthetic retail model. It is not pricing, legal, financial, operational, compliance, or merchandising advice. The sources below justify why some variables belong in the model. The probabilities are invented so the reasoning path is easy to inspect.
The Operating Problem Is Usually Wider Than The Metric
A slow item can be a substitute, a complement, a price-tier anchor, or a reason a shopper trusts the category. Removing it may improve inventory turns or it may move demand to a lower-margin substitute, trigger lost sales, increase markdown pressure elsewhere, or make the category feel incomplete.
Why The Dashboard Can Mislead
The dashboard can mislead if it treats each SKU as independent. A product with low unit sales may still protect a basket or price tier. A product with high sales may cannibalize a higher-margin item. Assortment work becomes causal when the team asks what changes after a SKU or tier is actually removed.
Plain-language modeling note
A Bayesian belief network, or BBN, is a graph for asking conditional questions. Each node is a condition, each arrow says one condition informs another, and each probability is explicit. You do not need to know the SDK to read the graph: the SDK code is only there when we need a repeatable action query.
The Question For This Example
This example asks how assortment-profit-leak risk changes after observing tight shelf space, high SKU overlap, weak supplier fill, and weak local demand signals, and what changes if the category role, price-tier coverage, and supply are improved.
The target outcome is AssortmentProfitLeak, which means assortment profit leak in this teaching model.
A Small Model Of The Situation
The model treats assortment as a category-level decision with binary states. It leaves out real planograms, vendor funding, exact demand curves, store clusters, perishable spoilage, and contractual constraints.
The graph has 16 nodes:
CategoryRoleClarity: Category role clarity (clear / unclear)ShelfSpaceConstraint: Shelf space constraint (open / tight)SKUOverlap: SKU overlap (low / high)PrivateLabelPush: Private label push (low / high)SupplierFillRate: Supplier fill rate (adequate / low)LocalDemandSignal: Local demand signal (strong / weak)PriceTierCoverage: Price tier coverage (good / poor)StockoutProbability: Stockout probability (low / high)SubstitutionElasticity: Substitution elasticity (adequate / low)BasketComplementarity: Basket complementarity (adequate / low)SlowMovingInventory: Slow-moving inventory (low / high)MarkdownPressure: Markdown pressure (low / high)CustomerChoiceOverload: Customer choice overload (low / high)LostSalesRisk: Lost sales risk (low / high)GrossMarginMix: Gross margin mix (good / poor)AssortmentProfitLeak: Assortment profit leak (no / yes)

What Is Sourced And What Is Synthetic
Deloitte’s retail outlook supports inventory visibility, personalization, and profitable transaction pressure. Current assortment-optimization research supports modeling basket behavior, complements, substitutes, stockouts, and inventory allocation as connected decisions.
Basket behavior- Recent assortment research models customers as basket shoppers and motivates including complementarity and substitution in assortment decisions.
Inventory and allocation- Fulfillment and inventory-allocation research supports connecting assortment to local fulfillment, lost sales, and inventory transfer cost.
Retail operating pressure- Deloitte’s outlook supports including inventory visibility, merchandising, personalization, and margin pressure as practical retail constraints.
Boundary of the evidence
The sources support the general mechanisms in the graph. They do not estimate this article’s node states, thresholds, or conditional probability values. Those are synthetic teaching values.
The Query The Graph Cannot Show By Itself
The visual graph is the best way to inspect the structure. The code-backed query is there for a narrower reason: we want to separate what is learned by observing a messy retail case from what changes if one condition is set differently.
Using the Darkstar Python SDK, a subscribed SDK user can load the same BBN JSON, ask for the target probability after evidence is entered, then run the action query by setting a node before querying again. The download includes this as illustrative SDK code, while the standalone query_example.py reproduces the article numbers without shipping the SDK.
import json
from darkstar import DiscreteModel
TARGET = "AssortmentProfitLeak"
OBSERVED_EVIDENCE = {
"ShelfSpaceConstraint": "tight",
"SKUOverlap": "high",
"SupplierFillRate": "low",
"LocalDemandSignal": "weak"
}
INTERVENTION_CONTEXT = {
"ShelfSpaceConstraint": "tight",
"SKUOverlap": "high",
"LocalDemandSignal": "weak"
}
INTERVENTION = {
"CategoryRoleClarity": "clear",
"PriceTierCoverage": "good",
"SupplierFillRate": "adequate"
}
def probability_after_observing(model, evidence):
query = {"nodes": [TARGET], "evidence": evidence}
result = json.loads(model.pquery(json.dumps(query)))
return result[TARGET]["yes"]
def probability_after_setting(model, setting, evidence):
changed_model = model.intervene(json.dumps(setting))
return probability_after_observing(changed_model, evidence)
with DiscreteModel(model_json) as model:
observed = probability_after_observing(model, OBSERVED_EVIDENCE)
acted = probability_after_setting(model, INTERVENTION, INTERVENTION_CONTEXT)
That is the article’s main modeling distinction. Observing a pattern is not the same as setting one part of the system differently.
The standalone query code gives this synthetic result:
Baseline assortment profit leak: 19.0%
Observed scenario (tight shelf, overlapping SKUs, and weak supply): 23.2%
Action scenario (clear role, better tiers, and adequate supply): 19.1%
Same context with the action left unfavorable: 26.9%
Synthetic reduction versus the observed scenario: 4.1 percentage points
What We Learn By Observing The Situation
The observed scenario sets:
- Shelf space constraint = tight
- SKU overlap = high
- Supplier fill rate = low
- Local demand signal = weak
In the observed scenario, tight shelf space, overlapping SKUs, low supplier fill, and weak local demand signals raise profit-leak risk. The model reads that as a fragile assortment decision: there is pressure to prune, but weak evidence about local substitution.

What Changes If We Set One Condition Differently
The action scenario sets:
- Category role clarity = clear
- Price tier coverage = good
- Supplier fill rate = adequate
The action query clarifies the category role, improves price-tier coverage, and makes supply adequate. The result does not claim the assortment is optimal. It shows how the risk falls when the decision is less blind to role, tier, and availability.
What This Example Cannot Prove
This model cannot choose a product list, solve an assortment optimization problem, or estimate store-level demand. It is a teaching model for why substitute and complement paths matter before pruning.
Try this in the shared model
Open the companion model, change one upstream condition at a time, and watch the target probability move. Start with the observed scenario above, then reset one condition that looks actionable. The point is to compare stories, not to treat the toy probabilities as a forecast.
Try The Model
Open the companion Darkstar model: Open Retail Assortment Substitution BBN
In the shared model, set SKUOverlap high but BasketComplementarity strong. Then set overlap high and complementarity low. The same overlap signal has different meaning under different basket structure.
Download the teaching package: Retail Assortment Substitution BBN ZIP
The ZIP contains synthetic model and example code only. It excludes planograms, supplier data, transaction data, proprietary optimization code, the SDK package, and chart-generation code.


Leave a Reply