NEW: The Decision Factory — a novel about decisions under uncertainty. Get it on Amazon
Decision Science · · Adam DeJans Jr.

Substitution Is Part of Demand

Why SKU-level demand is not independent when customers switch products, and how to model substitution without turning inventory optimization into fiction.

supply-chaininventoryforecastingdecision-sciencesimulationoptimization

Substitution Is Part of Demand

A customer wants a 12-pack of sparkling water. It is out of stock. They buy the 8-pack instead.

What was demand for the 8-pack?

If your answer is simply “one unit,” you have already lost information.

That sale was partly demand for the 8-pack and partly demand transferred from another product. The distinction matters because the next decision is not to explain yesterday’s sales. The next decision is how much of each product to buy, produce, allocate, or stock.

This is one of the easiest ways to build an inventory model that looks sophisticated and behaves stupidly: forecast every SKU independently, optimize every SKU independently, and then act surprised when products cannibalize each other.

Real demand often lives at the level of a customer need. SKUs are competing ways to satisfy it.

Start With the Decision

Before building a substitution model, write down the actual decision.

Maybe you choose order quantities:

[ q_i \in {0, p_i, 2p_i, \ldots} ]

where (p_i) is a case pack.

Maybe you choose assortment:

[ y_i \in {0,1} ]

where (y_i=1) means SKU (i) is offered.

Maybe you allocate scarce inventory across locations:

[ x_{il} \ge 0 ]

for product (i) and location (l).

These decisions change availability. Availability changes customer choice. Customer choice changes realized demand.

That feedback loop is the problem.

If the model treats demand as fixed regardless of the decisions it makes, it can systematically misvalue inventory.

The Questions I Would Ask First

Before reaching for a choice model, ask operational questions:

  • When a SKU stocks out, what do customers actually do: substitute, delay, abandon, or buy elsewhere?
  • Which products are credible substitutes and which only look similar in a product hierarchy?
  • Is substitution symmetric? If A is unavailable, customers may buy B, while customers wanting B may never buy A.
  • Does substitution depend on price, promotion, pack size, brand, location, channel, or time?
  • Can customers observe that an item is unavailable before they arrive?
  • Are we modeling physical shelf availability, online availability, or both?
  • Does the business control assortment and price, or only replenishment?
  • What decision would change if the substitution estimate changed?

That last question is important. A beautiful substitution matrix that never changes a decision is analytics decoration.

Observed Sales Are an Outcome of Availability

Let (D_i) represent latent first-choice demand for SKU (i). If every product were available, this is the demand we would like to understand.

Observed sales are different.

For a simple two-product example, suppose A stocks out after selling (I_A) units. Some unmet demand for A transfers to B. Then sales of B might look like:

[ S_B = \min\left(I_B, D_B + \alpha_{AB}(D_A-I_A)^+\right) ]

where (\alpha_{AB}) is the fraction of unmet A demand that switches to B.

Already, two things are obvious.

First, high sales for B do not necessarily mean high native demand for B.

Second, stocking more A can reduce sales of B.

That means the marginal value of another unit of A is not simply its own expected margin. It includes the effect on the rest of the portfolio.

A Substitution Matrix Is a Useful Starting Point

For products (i) and (j), define

[ P_{ij}=P(\text{customer chooses }j \mid \text{first choice }i\text{ unavailable}). ]

Include an outside option (0):

[ P_{i0}=P(\text{lost sale} \mid i\text{ unavailable}). ]

Rows should satisfy

[ \sum_j P_{ij}+P_{i0}=1. ]

This is not a universal law of customer behavior. It is a practical representation you can simulate, estimate, challenge, and replace later.

The outside option matters enormously. Assuming every stockout transfers to another SKU creates imaginary demand recovery and usually makes inventory look safer than it is.

Substitution Can Cascade

Suppose A is unavailable and a customer tries B. B is also unavailable. Do they try C?

Sometimes yes.

This creates sequential substitution. A simple simulator can represent it directly:

  1. Generate the customer’s first choice.
  2. Check availability.
  3. If unavailable, sample the next choice from the substitution probabilities.
  4. Continue until a product is purchased or the customer exits.
  5. Update inventory immediately.

This is often easier to reason about than forcing the entire behavior into a closed-form formula.

It also exposes an important fact: substitution is state dependent. The demand realized by a SKU depends on what else is still available at that moment.

The Optimization Problem Is Coupled

Without substitution, a naive expected-profit objective might be written as

[ \max_q \sum_i E[\pi_i(q_i,D_i)]. ]

Each SKU appears separable.

With substitution, profit is closer to

[ \max_q E[\Pi(q,D,P)], ]

where the inventory vector (q), joint demand realization (D), and substitution behavior (P) interact.

Now the value of stocking SKU A depends on how much B and C you stock.

That destroys a lot of convenient SKU-by-SKU logic.

It also creates opportunities. If two products are strong substitutes, the portfolio may need less total buffer than two independent service-level calculations suggest. If substitution is weak, pretending otherwise can create expensive stockouts.

Constraints Still Matter

The real system probably has more than demand uncertainty.

You may have supplier MOQs:

[ q_i \ge M_i z_i ]

case packs:

[ q_i=p_i k_i, \qquad k_i\in\mathbb{Z}_+ ]

shared purchasing capacity:

[ \sum_i c_i q_i \le B ]

warehouse capacity:

[ \sum_i v_i q_i \le C ]

or vendor-level minimums:

[ \sum_{i\in V} q_i \ge M_V z_V. ]

These constraints interact with substitution.

A high-MOQ product may be unattractive by itself but useful because it absorbs demand from several nearby products. Another SKU may look profitable in isolation but add little portfolio value because customers already have good alternatives.

This is why ranking SKUs by margin, forecast, or standalone stockout cost can fail under shared constraints.

Marginal Value Should Be Portfolio Value

A useful way to think about inventory is through the marginal value of the next executable increment.

For SKU (i):

[ \Delta_i = E[\Pi(q+p_i e_i)]-E[\Pi(q)]. ]

Here (e_i) increments only SKU (i), and the simulator allows customers to substitute under both inventory states.

That difference automatically includes cannibalization and demand recovery.

If adding a case of A mostly steals sales from B, its marginal value will be lower than a standalone model suggests.

If adding A prevents customers from abandoning the category entirely, its marginal value may be much higher.

That is the economic quantity you care about.

Uncertainty Is Bigger Than Forecast Error

There are at least three uncertain objects in this problem.

First-choice demand

You do not know how many customers will initially want each product.

Substitution behavior

You do not know exactly what customers will do when something is unavailable.

Operational availability

Receipts can be late, inventory records can be wrong, and replenishment can miss the shelf even when the network technically has stock.

A useful scenario therefore contains more than a vector of SKU demand:

[ \omega = (D, P, L, A, \ldots) ]

where (L) can represent lead-time outcomes and (A) operational availability.

Do not automatically make every uncertain quantity independent. A promotion can increase demand for several substitutes simultaneously. A supplier disruption can affect multiple related SKUs. Weather can move an entire category.

Joint scenarios matter when decisions are coupled.

Estimating Substitution Is Hard

Historical data is observational. Availability was not randomized.

That creates a nasty identification problem.

Suppose B sells more whenever A is out of stock. That is evidence of substitution, but it is not automatically the substitution rate. A and B may both sell more on high-demand days. Promotions may overlap. Stores with poor replenishment may have other operational differences.

Useful evidence can come from:

  • stockout episodes with accurate intraday availability,
  • controlled assortment tests,
  • online choice and clickstream behavior,
  • basket transitions,
  • store or region variation,
  • customer-level choice histories,
  • deliberate experiments where commercially acceptable.

The goal is not to estimate a giant matrix because you can. Estimate the relationships that materially affect decisions.

Use Structure Before Complexity

A full customer-choice model across 50,000 SKUs is usually nonsense.

Most products do not compete directly.

Build substitution neighborhoods. A product might only substitute within the same category, size band, brand tier, application, or compatible family.

Represent this as a sparse graph.

Then simulation and optimization can operate on local connected components instead of the entire catalog.

This is both computationally cheaper and easier to explain.

A sparse model with believable edges beats a dense model filled with tiny invented probabilities.

Do Not Train on Stockout-Corrupted Labels and Call It Demand

This is the circular failure mode.

A product stocks out frequently. Observed sales are low. The forecasting model learns low demand. The optimizer orders less. The product stocks out more often.

Substitution makes the loop worse because transferred sales inflate substitute SKUs at the same time.

You can end up teaching the system that the product you failed to stock has weak demand and the product customers reluctantly accepted has strong demand.

That is not learning customer preference. It is learning your own historical inventory policy.

At minimum, availability should be part of the data-generating story.

Evaluate the Decision, Not Just the Choice Model

A substitution model can have better likelihood and still produce worse inventory decisions.

The production test should be economic.

Take candidate demand/substitution models and run the downstream policy under held-out historical periods or realistic simulated scenarios. Compare:

  • contribution margin,
  • lost sales,
  • units abandoned to the outside option,
  • inventory holding cost,
  • markdown or disposal cost,
  • working capital,
  • category availability,
  • order frequency and MOQ activation,
  • decision stability,
  • total economic regret versus a stronger benchmark.

Also compare the actual decisions.

If two substitution models produce almost identical order quantities across the portfolio, the extra modeling complexity may not be worth operating.

A Practical Simulation Architecture

A useful implementation can be surprisingly simple.

At each simulated period:

  1. Start from the actual state: on-hand inventory, pipeline, open orders, prices, assortment, and constraints.
  2. Generate first-choice customer demand from a joint probabilistic model.
  3. Process purchases and substitutions against available inventory.
  4. Record fulfilled first choices, transferred sales, and lost sales separately.
  5. Advance lead times and receive inventory.
  6. Recompute the state visible to the policy.
  7. Run the replenishment or allocation policy.
  8. Apply executable constraints such as packs, MOQs, budgets, and capacity.
  9. Repeat over the evaluation horizon.

The key is step 4. Preserve the decomposition.

A sale should not erase the path that created it.

Log the Decision Trace

In production, I would want a trace for every meaningful recommendation.

For each SKU or substitution group, log the state, first-choice demand distribution, substitution neighborhood, outside-option probability, recommended quantity, binding constraints, expected economics, and marginal value of the next executable increment.

Also log counterfactuals.

What would we order if substitution were disabled?

What would we order if the strongest substitute were unavailable?

What would we order if the outside-option probability were 20% higher?

Those counterfactuals make debugging much faster than staring at a final order quantity and guessing why it moved.

Common Failure Modes

Treating product hierarchy as customer behavior

Two SKUs being in the same category does not mean customers consider them substitutes.

Assuming substitution is symmetric

Premium customers may trade down when premium inventory is unavailable. Value customers may not trade up.

Ignoring the outside option

Some demand disappears. Some customers wait. Some go to a competitor. Forced substitution overstates recovered sales.

Using one static matrix everywhere

Behavior can vary by location, channel, season, price, and promotion.

Double counting demand

If transferred sales are used to inflate the receiving SKU’s baseline demand while also modeling substitution explicitly, the same customer demand can appear twice.

Optimizing each SKU independently

The entire point is that availability decisions interact.

Measuring only forecast accuracy

A better prediction of SKU sales is not necessarily a better estimate of latent preference and not necessarily a better ordering policy.

Building a choice model that cannot run operationally

If scoring substitution turns a five-minute ordering process into a six-hour research job, you have not finished the engineering problem.

What I Would Do in Practice

Start with one category where substitution is commercially obvious and inventory decisions matter.

Build a baseline policy that ignores substitution. Then build a sparse, simple substitution model with an explicit outside option. Run both policies on the same scenarios using common random numbers.

Measure paired economic differences.

Then stress the assumptions. Increase and decrease substitution rates. Remove the strongest edges. Change outside-option probabilities. Shock lead times. Tighten shared capacity.

Look for decision boundaries.

Where does substitution actually change what you order or allocate?

Those are the places worth modeling better.

If the policy barely changes, stop polishing the choice model.

If the policy changes materially and economics improve out of sample, you have found something valuable.

The Bigger Point

Demand is not a spreadsheet column attached permanently to a SKU.

It is the result of customers arriving with preferences, seeing a particular state of availability and price, and making choices.

Your inventory policy helps create the sales data you later call demand.

Once you see that feedback loop, substitution stops being a forecasting side project. It becomes part of the decision model.

And that is where it belongs.