Skip to content
Was It Causal?

An Experiment-Calibrated Marketing Mix Model

A mix model that fits three years of weekly data almost perfectly and gets the channel contributions badly wrong, and what one geo holdout does about it.

The decision
How should next quarter's media budget be split across five channels?
The method
Adstock and saturation estimated by grid search with non-negative least squares, fitted twice, once on history alone and once anchored to a geo holdout, with a residual block bootstrap on the history-only fit.

STEP 01

The business decision

Five channels, roughly $6197k a year, and a planning cycle that has to split next quarter’s budget between them. Three years of clean weekly history are available.

The request is the usual one: build a mix model, tell us what each channel contributed, and recommend an allocation.

STEP 02

The tempting metric

Model fit. It is the number every mix model is sold on, and this one is excellent: R² of 0.964 against three years of weekly conversions, with mean absolute percentage error of 1.3%.

  • Actual
  • Predicted
1,200 1,400 1,600 1,800 2,000 2,200 W0 W26 W52 W78 W104 W130 Conversions Actual, W0: 1,218.2 Actual, : 1,298.9 Actual, : 1,361.8 Actual, : 1,430.5 Actual, : 1,504.6 Actual, : 1,467.6 Actual, : 1,480.8 Actual, : 1,554.3 Actual, : 1,514.2 Actual, : 1,526.4 Actual, : 1,578.3 Actual, : 1,567.2 Actual, : 1,679.7 Actual, W13: 1,726.5 Actual, : 1,549.0 Actual, : 1,604.3 Actual, : 1,628.1 Actual, : 1,703.6 Actual, : 1,718.7 Actual, : 1,721.8 Actual, : 1,704.8 Actual, : 1,714.1 Actual, : 1,700.3 Actual, : 1,731.6 Actual, : 1,676.4 Actual, : 1,812.4 Actual, W26: 1,801.7 Actual, : 1,641.9 Actual, : 1,636.6 Actual, : 1,710.2 Actual, : 1,662.7 Actual, : 1,632.4 Actual, : 1,638.5 Actual, : 1,595.4 Actual, : 1,545.3 Actual, : 1,598.7 Actual, : 1,615.3 Actual, : 1,568.5 Actual, : 1,550.8 Actual, W39: 1,531.3 Actual, : 1,543.4 Actual, : 1,627.4 Actual, : 1,668.6 Actual, : 1,679.3 Actual, : 1,685.3 Actual, : 1,842.7 Actual, : 1,896.3 Actual, : 1,882.9 Actual, : 1,757.7 Actual, : 1,657.0 Actual, : 1,582.0 Actual, : 1,647.5 Actual, W52: 1,469.3 Actual, : 1,543.6 Actual, : 1,470.3 Actual, : 1,490.5 Actual, : 1,520.8 Actual, : 1,520.4 Actual, : 1,524.1 Actual, : 1,560.4 Actual, : 1,696.8 Actual, : 1,573.3 Actual, : 1,637.4 Actual, : 1,705.9 Actual, : 1,824.9 Actual, W65: 1,793.9 Actual, : 1,680.8 Actual, : 1,745.2 Actual, : 1,746.1 Actual, : 1,792.5 Actual, : 1,727.1 Actual, : 1,784.0 Actual, : 1,812.5 Actual, : 1,762.0 Actual, : 1,813.6 Actual, : 1,743.0 Actual, : 1,752.4 Actual, : 1,861.8 Actual, W78: 1,884.3 Actual, : 1,759.9 Actual, : 1,765.2 Actual, : 1,794.8 Actual, : 1,772.9 Actual, : 1,792.3 Actual, : 1,750.7 Actual, : 1,759.8 Actual, : 1,686.5 Actual, : 1,706.7 Actual, : 1,695.7 Actual, : 1,715.7 Actual, : 1,582.3 Actual, W91: 1,660.8 Actual, : 1,649.8 Actual, : 1,710.2 Actual, : 1,752.9 Actual, : 1,782.8 Actual, : 1,781.0 Actual, : 1,987.4 Actual, : 1,931.9 Actual, : 1,891.1 Actual, : 1,784.8 Actual, : 1,779.2 Actual, : 1,630.8 Actual, : 1,662.7 Actual, W104: 1,595.6 Actual, : 1,608.2 Actual, : 1,576.4 Actual, : 1,587.0 Actual, : 1,587.4 Actual, : 1,653.6 Actual, : 1,621.9 Actual, : 1,666.9 Actual, : 1,706.9 Actual, : 1,715.6 Actual, : 1,685.6 Actual, : 1,745.0 Actual, : 1,882.6 Actual, W117: 1,926.4 Actual, : 1,866.5 Actual, : 1,790.1 Actual, : 1,841.2 Actual, : 1,866.4 Actual, : 1,812.1 Actual, : 1,857.7 Actual, : 1,821.3 Actual, : 1,822.8 Actual, : 1,859.2 Actual, : 1,873.9 Actual, : 1,819.9 Actual, : 2,017.7 Actual, W130: 2,008.9 Actual, : 1,857.4 Actual, : 1,834.5 Actual, : 1,822.9 Actual, : 1,776.7 Actual, : 1,867.5 Actual, : 1,834.7 Actual, : 1,787.9 Actual, : 1,797.7 Actual, : 1,781.4 Actual, : 1,667.0 Actual, : 1,724.0 Actual, : 1,766.6 Actual, W143: 1,810.2 Actual, : 1,839.5 Actual, : 1,800.6 Actual, : 1,868.5 Actual, : 1,821.6 Actual, : 1,864.8 Actual, : 2,040.6 Actual, : 2,064.6 Actual, : 2,038.9 Actual, : 1,926.7 Actual, : 1,875.7 Actual, : 1,712.4 Actual, : 1,783.7 Actual Predicted, W0: 1,209.9 Predicted, : 1,339.8 Predicted, : 1,380.4 Predicted, : 1,420.1 Predicted, : 1,452.6 Predicted, : 1,460.2 Predicted, : 1,481.5 Predicted, : 1,501.1 Predicted, : 1,513.4 Predicted, : 1,512.8 Predicted, : 1,556.5 Predicted, : 1,578.0 Predicted, : 1,662.5 Predicted, W13: 1,730.3 Predicted, : 1,600.1 Predicted, : 1,617.0 Predicted, : 1,662.7 Predicted, : 1,700.5 Predicted, : 1,695.6 Predicted, : 1,702.4 Predicted, : 1,674.3 Predicted, : 1,703.2 Predicted, : 1,726.9 Predicted, : 1,743.1 Predicted, : 1,693.4 Predicted, : 1,844.8 Predicted, W26: 1,841.5 Predicted, : 1,674.7 Predicted, : 1,657.5 Predicted, : 1,695.0 Predicted, : 1,660.3 Predicted, : 1,664.2 Predicted, : 1,664.9 Predicted, : 1,586.9 Predicted, : 1,547.2 Predicted, : 1,564.4 Predicted, : 1,558.2 Predicted, : 1,570.5 Predicted, : 1,548.2 Predicted, W39: 1,520.7 Predicted, : 1,580.5 Predicted, : 1,639.9 Predicted, : 1,671.5 Predicted, : 1,663.9 Predicted, : 1,721.8 Predicted, : 1,839.5 Predicted, : 1,902.6 Predicted, : 1,871.8 Predicted, : 1,732.4 Predicted, : 1,637.9 Predicted, : 1,592.8 Predicted, : 1,624.6 Predicted, W52: 1,510.8 Predicted, : 1,544.1 Predicted, : 1,487.3 Predicted, : 1,514.7 Predicted, : 1,520.9 Predicted, : 1,512.7 Predicted, : 1,535.2 Predicted, : 1,567.8 Predicted, : 1,674.0 Predicted, : 1,642.1 Predicted, : 1,618.6 Predicted, : 1,685.0 Predicted, : 1,796.6 Predicted, W65: 1,788.7 Predicted, : 1,707.3 Predicted, : 1,720.0 Predicted, : 1,726.3 Predicted, : 1,776.0 Predicted, : 1,753.9 Predicted, : 1,774.1 Predicted, : 1,789.5 Predicted, : 1,732.4 Predicted, : 1,756.3 Predicted, : 1,763.4 Predicted, : 1,750.3 Predicted, : 1,875.6 Predicted, W78: 1,903.5 Predicted, : 1,784.6 Predicted, : 1,735.8 Predicted, : 1,759.5 Predicted, : 1,773.4 Predicted, : 1,744.0 Predicted, : 1,723.7 Predicted, : 1,729.0 Predicted, : 1,694.2 Predicted, : 1,683.8 Predicted, : 1,668.1 Predicted, : 1,673.5 Predicted, : 1,632.2 Predicted, W91: 1,679.1 Predicted, : 1,692.8 Predicted, : 1,729.6 Predicted, : 1,752.7 Predicted, : 1,769.3 Predicted, : 1,803.7 Predicted, : 1,970.5 Predicted, : 1,930.4 Predicted, : 1,921.6 Predicted, : 1,777.9 Predicted, : 1,768.5 Predicted, : 1,683.1 Predicted, : 1,648.9 Predicted, W104: 1,561.3 Predicted, : 1,609.0 Predicted, : 1,590.3 Predicted, : 1,597.3 Predicted, : 1,614.3 Predicted, : 1,645.3 Predicted, : 1,663.6 Predicted, : 1,654.5 Predicted, : 1,697.3 Predicted, : 1,679.6 Predicted, : 1,728.4 Predicted, : 1,729.5 Predicted, : 1,886.9 Predicted, W117: 1,914.9 Predicted, : 1,820.2 Predicted, : 1,830.9 Predicted, : 1,813.1 Predicted, : 1,849.0 Predicted, : 1,811.1 Predicted, : 1,877.8 Predicted, : 1,833.3 Predicted, : 1,868.1 Predicted, : 1,859.6 Predicted, : 1,900.1 Predicted, : 1,855.0 Predicted, : 1,989.6 Predicted, W130: 1,987.3 Predicted, : 1,861.7 Predicted, : 1,838.7 Predicted, : 1,828.8 Predicted, : 1,826.3 Predicted, : 1,880.6 Predicted, : 1,801.2 Predicted, : 1,803.2 Predicted, : 1,788.1 Predicted, : 1,770.7 Predicted, : 1,718.3 Predicted, : 1,753.2 Predicted, : 1,735.5 Predicted, W143: 1,778.9 Predicted, : 1,776.7 Predicted, : 1,816.4 Predicted, : 1,841.8 Predicted, : 1,849.0 Predicted, : 1,865.9 Predicted, : 2,032.5 Predicted, : 2,040.8 Predicted, : 2,065.4 Predicted, : 1,865.7 Predicted, : 1,864.3 Predicted, : 1,769.1 Predicted, : 1,787.8 Predicted
Show the data
Period Actual Predicted
W0 1,218.2 1,209.9
1,298.9 1,339.8
1,361.8 1,380.4
1,430.5 1,420.1
1,504.6 1,452.6
1,467.6 1,460.2
1,480.8 1,481.5
1,554.3 1,501.1
1,514.2 1,513.4
1,526.4 1,512.8
1,578.3 1,556.5
1,567.2 1,578.0
1,679.7 1,662.5
W13 1,726.5 1,730.3
1,549.0 1,600.1
1,604.3 1,617.0
1,628.1 1,662.7
1,703.6 1,700.5
1,718.7 1,695.6
1,721.8 1,702.4
1,704.8 1,674.3
1,714.1 1,703.2
1,700.3 1,726.9
1,731.6 1,743.1
1,676.4 1,693.4
1,812.4 1,844.8
W26 1,801.7 1,841.5
1,641.9 1,674.7
1,636.6 1,657.5
1,710.2 1,695.0
1,662.7 1,660.3
1,632.4 1,664.2
1,638.5 1,664.9
1,595.4 1,586.9
1,545.3 1,547.2
1,598.7 1,564.4
1,615.3 1,558.2
1,568.5 1,570.5
1,550.8 1,548.2
W39 1,531.3 1,520.7
1,543.4 1,580.5
1,627.4 1,639.9
1,668.6 1,671.5
1,679.3 1,663.9
1,685.3 1,721.8
1,842.7 1,839.5
1,896.3 1,902.6
1,882.9 1,871.8
1,757.7 1,732.4
1,657.0 1,637.9
1,582.0 1,592.8
1,647.5 1,624.6
W52 1,469.3 1,510.8
1,543.6 1,544.1
1,470.3 1,487.3
1,490.5 1,514.7
1,520.8 1,520.9
1,520.4 1,512.7
1,524.1 1,535.2
1,560.4 1,567.8
1,696.8 1,674.0
1,573.3 1,642.1
1,637.4 1,618.6
1,705.9 1,685.0
1,824.9 1,796.6
W65 1,793.9 1,788.7
1,680.8 1,707.3
1,745.2 1,720.0
1,746.1 1,726.3
1,792.5 1,776.0
1,727.1 1,753.9
1,784.0 1,774.1
1,812.5 1,789.5
1,762.0 1,732.4
1,813.6 1,756.3
1,743.0 1,763.4
1,752.4 1,750.3
1,861.8 1,875.6
W78 1,884.3 1,903.5
1,759.9 1,784.6
1,765.2 1,735.8
1,794.8 1,759.5
1,772.9 1,773.4
1,792.3 1,744.0
1,750.7 1,723.7
1,759.8 1,729.0
1,686.5 1,694.2
1,706.7 1,683.8
1,695.7 1,668.1
1,715.7 1,673.5
1,582.3 1,632.2
W91 1,660.8 1,679.1
1,649.8 1,692.8
1,710.2 1,729.6
1,752.9 1,752.7
1,782.8 1,769.3
1,781.0 1,803.7
1,987.4 1,970.5
1,931.9 1,930.4
1,891.1 1,921.6
1,784.8 1,777.9
1,779.2 1,768.5
1,630.8 1,683.1
1,662.7 1,648.9
W104 1,595.6 1,561.3
1,608.2 1,609.0
1,576.4 1,590.3
1,587.0 1,597.3
1,587.4 1,614.3
1,653.6 1,645.3
1,621.9 1,663.6
1,666.9 1,654.5
1,706.9 1,697.3
1,715.6 1,679.6
1,685.6 1,728.4
1,745.0 1,729.5
1,882.6 1,886.9
W117 1,926.4 1,914.9
1,866.5 1,820.2
1,790.1 1,830.9
1,841.2 1,813.1
1,866.4 1,849.0
1,812.1 1,811.1
1,857.7 1,877.8
1,821.3 1,833.3
1,822.8 1,868.1
1,859.2 1,859.6
1,873.9 1,900.1
1,819.9 1,855.0
2,017.7 1,989.6
W130 2,008.9 1,987.3
1,857.4 1,861.7
1,834.5 1,838.7
1,822.9 1,828.8
1,776.7 1,826.3
1,867.5 1,880.6
1,834.7 1,801.2
1,787.9 1,803.2
1,797.7 1,788.1
1,781.4 1,770.7
1,667.0 1,718.3
1,724.0 1,753.2
1,766.6 1,735.5
W143 1,810.2 1,778.9
1,839.5 1,776.7
1,800.6 1,816.4
1,868.5 1,841.8
1,821.6 1,849.0
1,864.8 1,865.9
2,040.6 2,032.5
2,064.6 2,040.8
2,038.9 2,065.4
1,926.7 1,865.7
1,875.7 1,864.3
1,712.4 1,769.1
1,783.7 1,787.8
Actual and predicted weekly conversions over three years. The model tracks the series almost exactly, including both Q4 peaks. Simulated data · scripts/mmm_calibrated.py

A chart like this ends most model reviews. It should not end this one.

STEP 03

Why that may be wrong

Fit measures whether the model can reproduce the outcome. It says nothing about whether it has divided the credit correctly, and those are separable problems.

Media spend does not vary independently of everything else. Budgets rise in Q4 and so does demand. Worse, branded search spend is bid against demand: when more people search for the brand, the channel spends more, automatically, every week. Its spend and the underlying demand curve are nearly the same shape.

Given two variables that move together, least squares has no way to tell which one is doing the work. It will assign the credit in whatever combination minimizes error, and a great many combinations minimize error almost equally well.

STEP 04

Data available and missing

Available. 156 weeks of spend by channel, conversions, a price index, promotional periods, and the calendar.

Missing. Any variation in spend that was not decided in response to something else. Every budget in this history was set by people reacting to demand, competitors, and last quarter’s results. That is the whole problem: observational media data contains almost no exogenous variation, and exogenous variation is what identifies a causal effect.

Also available, and this is what makes the second half of the analysis possible: a geo holdout on paid social measuring incremental cost per conversion at $95, with a 95% interval from $66 to $173.

STEP 05

The target quantity

For each channel, the incremental conversions caused by its spend, and the shape of the curve relating the two, so that a marginal return can be computed at any budget level.

Not the share of conversions that correlate with each channel. That quantity is always estimable and is not what anyone is asking for.

STEP 06

The strongest feasible design

Fit the model twice.

Model one: history alone. Geometric adstock and a concave saturation curve per channel, with decay and half-saturation found by grid search and the coefficients solved by least squares at each candidate. Controls for price, promotions, trend, annual seasonality, and a holiday term. Media coefficients constrained to be non-negative.

Model two: anchored to the experiment. Identical, except that paid social’s contribution is fixed so its implied cost per conversion matches the geo holdout. The remaining channels are fitted against what is left.

Because this is simulated, both can be scored against a truth no real project has.

STEP 07

Assumptions and failure modes

STEP 08

Worked example and diagnostics

What the history-only model concluded

  • True
  • History only
  • Calibrated
0 20,000 40,000 60,000 80,000 100,000 Branded srch Non-brand srch Paid social Online video Affiliate Conversions True, Branded srch: 29,368.7 True, Non-brand srch: 37,817.9 True, Paid social: 39,107.1 True, Online video: 27,417.7 True, Affiliate: 15,923.9 History only, Branded srch: 74,465.3 History only, Non-brand srch: 26,613.6 History only, Paid social: 79,515.7 History only, Online video: 20,220.7 History only, Affiliate: 5,565.2 Calibrated, Branded srch: 81,670.9 Calibrated, Non-brand srch: 25,910.8 Calibrated, Paid social: 37,962.7 Calibrated, Online video: 19,896.6 Calibrated, Affiliate: 5,627.3
Show the data
Period True History only Calibrated
Branded srch 29,368.7 74,465.3 81,670.9
Non-brand srch 37,817.9 26,613.6 25,910.8
Paid social 39,107.1 79,515.7 37,962.7
Online video 27,417.7 20,220.7 19,896.6
Affiliate 15,923.9 5,565.2 5,627.3
Estimated contribution against the truth, by channel. The model overstates branded search by 154% and paid social by 103%, while understating affiliate by 65%. Simulated data · scripts/mmm_calibrated.py

Branded search produced 29,369 conversions. The model credits it with 74,465, an overstatement of 154%. That is the channel whose spend tracks demand, and it has absorbed a large share of the baseline.

That is one draw of the noise. Step nine refits the model a hundred times on resampled residuals and asks how stable that 154% is; the answer is that it is not, and the direction it fails in is the finding.

The error does not stop there. Because branded search takes credit that belongs elsewhere, every other channel is squeezed. Affiliate is understated by 65%, which matters more than it sounds: a model that cannot see a channel will recommend switching it off.

What the anchor changes

Fixing paid social to the experimental estimate brings that channel to within 3% of the truth, from 103%. Mean absolute error across all five channels falls from 76% to 61%.

That is an improvement and it is not a repair. Branded search is still overstated, slightly more than before, because the credit paid social gave up had to go somewhere and branded search is still the channel that most resembles the unexplained variation.

STEP 09

The estimate, with uncertainty

Branded search contribution from the history-only model, as error against the truth

+154% Bootstrap 95% −100% to +285%

A residual block bootstrap, the whole model refitted each time with the grid search included. Every refit reproduces the outcome about as well as this one. The estimate for the channel bid against demand ranges from nothing to nearly four times the truth across them.

Median across refits
−52%
R² of the fit
0.964
Refits
100

That interval is the identification problem made visible. Many divisions of credit between branded search and the demand it is bid against reproduce the series equally well, so the fit statistics are the same across the whole range and the noise decides where the estimator lands. The +154% above is where it landed on this draw. The median across refits is −52%, so the model does not even overstate the channel reliably: it is unidentified, and an unidentified estimate has no reliable direction. The other four channels swing about as widely.

A real account would produce the same bootstrap interval and no truth column to read it against. Which is the point: an interval on a mix model coefficient describes sampling noise, and sampling noise was never the problem.

The two models disagree sharply about the past and much less about the future.

Channel Now Reallocated Change
Affiliate $15k $4k − $12k out
Branded search $31k $19k − $12k out
Paid social $23k $18k − $5k out
Non-brand search $36k $43k + $8k in
Online video $14k $35k + $21k in

Both models recommend the same broad moves: cut branded search by roughly a third, cut affiliate hard, and roughly double online video. Across the whole budget they differ by about 7%.

That is worth being clear about rather than overselling. Calibration substantially changed the story about what happened, and changed the recommendation about what to do next only modestly, because the allocation rule depends on the shape of each curve near current spend and both models recovered similar shapes.

STEP 10

The recommendation

Act on the direction, not the decimals. Fund the next experiment on branded search.

  • Both models agree the current allocation is wrong in the same way. Four of the five moves point the same direction under both, including the three largest. Make those. Paid social is the exception, and it is the channel the anchor moved, so it is the one to hold: see what a mix model can and cannot do for why anchoring a level can leave the slope worse than it found it.
  • Do not report channel contributions from the history-only model. They are wrong by a factor of two on the largest line, and reporting them will eventually be discovered.
  • The affiliate recommendation is the one to hold back on. Both models want it cut to near zero, and both underestimate it by 65%. A model that cannot see a channel recommends deleting it, and that recommendation should not be executed on model evidence alone.
  • Branded search is the channel worth testing next, because it carries the largest spend and the largest identification problem, and because a holdout there would anchor the term currently absorbing everyone else’s credit.

STEP 11

What this does not establish

  • That mix models are unreliable in general. It establishes that identification, not estimation, is the binding constraint, and that fit statistics cannot detect the difference.
  • That the calibrated model is correct. It is closer on the channel that was tested and still substantially wrong on the channel that was not.
  • That 7% is how much calibration usually changes a budget. That number is a property of these curves; with different shapes the same anchor could change everything or nothing.
  • That the response curves have the right form. Concavity is assumed here, and on an S-shaped curve the allocation rule used in step nine is not valid.
  • Anything about the true contribution of channels in a real account. Every number here comes from a simulation whose answer was known in advance.

STEP 12

What to test next

  1. A geo holdout on branded search. Largest spend, worst identification, and the term currently absorbing the baseline. One test would improve the model more than another year of history.
  2. A spend-level test rather than an on-off test. Two arms at different budgets estimate the slope, which is what the allocation rule needs. An on-off test gives one point.
  3. A standing calibration cadence. One experiment per quarter, rotating across channels, keeps several anchors current instead of one going stale.
  4. Hold out a year. Refit on the first two years and check the third. It will not detect the identification problem, but it will catch overfitting, which is a different failure worth ruling out.

STEP 13

Technical appendix

Estimation, and three bugs worth naming Code

Adstock is geometric with one decay per channel. Saturation is concave, α·s/(s+k). Decay and k cannot be estimated by least squares, so they are grid searched while the coefficients are solved exactly at each candidate, cycling channel by channel until the fit stops improving. That is coordinate descent: no guarantee of a global optimum, and standard, because the joint search space is unaffordable.

Three things went wrong while building this, all of them instructive.

Unconstrained least squares returned nonsense. On collinear media it produced a coefficient implying affiliate had removed 172,000 conversions, offset by an equally large positive elsewhere. It fit better than the truth. Media coefficients are now constrained to be non-negative, which is why real mix models do the same.

The first calibration used a per-dollar rate. The holdout measured conversions per dollar at one spend level; applying that linearly across a saturating curve overstated the channel at every other level. Cost per conversion is scale free and transfers; a raw rate does not.

The anchor initially contradicted the simulation. Paid social’s true cost per conversion was $118 while the holdout being used to calibrate it said $88, so the anchor was dragging the model away from a truth it was supposed to reveal. The channel’s parameters were changed so the truth here, $92, sits inside the holdout’s own interval of $66 to $173, and the anchor is now read from that example’s output rather than retyped. The holdout’s point estimate, $95, still differs from the truth, because an experiment is an estimate too, and that gap is why the calibrated model lands within 3% of paid social’s truth rather than on it. A calibration anchor that disagrees with reality makes a model confidently worse, and in a real program nobody would be able to tell.

The bootstrap keeps the fitted series, resamples the residuals in 13-week blocks so autocorrelation survives, adds them back, and refits everything including the grid search, 100 times. Spend is held fixed, which is the conditional inference a regression makes anyway. The percentile interval that produces is about sampling noise only and cannot see bias, which is why it is reported next to the truth rather than instead of it.

Regenerated from seed 20260827 by the script named under each figure.

Why a Bayesian version would not have helped Technical

Bayesian mix models are frequently presented as the answer to this problem, on the grounds that priors regularize unstable estimates and the posterior communicates uncertainty honestly.

The second half is true and useful. The first is not. A prior does not add information about which of two collinear variables is causal; it adds information about what you believed before looking. If that belief is right the model improves, and if it is wrong the model becomes confidently wrong with a credible interval attached. Where the prior comes from an experiment, it works, and that is calibration by another name. Where it comes from judgment, the output inherits the judgment.

Bayesian estimation is a better way to express what a model does and does not know. It is not a substitute for variation the data does not contain.

Context

Best suited for

Programs with several channels, two or more years of history, genuine variation in spend, and at least one experiment available to anchor the model.

Data requirements

  • Two to three years of weekly spend and outcomes at consistent definitions
  • Controls for price, promotion, distribution, and anything else that moves demand
  • Real variation in spend that was not purely a response to demand
  • At least one experimental estimate, ideally recent, on a channel that matters

What changes by context

B2C ecommerce
The default case, and the one where branded search bidding creates the sharpest identification problem. Promotional calendars need explicit controls or they end up inside a media coefficient.
B2C subscription
Model retained value rather than trial starts, or the budget optimizes for subscribers who churn in month two. Adstock windows also need to be longer than the media planner expects.
Marketing-led
Where mix modeling earns its cost, because channel mix is the main lever and marketing controls both the spend and the measurement.
B2B SaaS
Lags of a quarter or more mean the model describes spend from long ago, and weekly observations at account-level volume are usually too noisy to fit. Most B2B programs are better served by experiments than by a mix model.

When it breaks down

  • Fewer than about two years of history, where seasonality alone consumes the degrees of freedom.
  • Spend that has been flat for years, which contains no information about the curve.
  • No experiments anywhere, since nothing else identifies the effects and the output will be confidently wrong.
  • Channels that were always bought together, which cannot be separated by any estimator.