A good marketing mix modeling example starts with a business decision rather than a regression: a finance team asks whether moving £30,000 from search to social next quarter is worth the risk, and the model’s job is to inform that one choice. This page works through that example end to end, using the invented Northstar case from the Vexpower course, covering the brief, an audit of the messy weekly data, a challenge to the model review, the contribution arithmetic under three scenarios and two margins, and the decision memo. Everything in it, including the data, the response curves and the model cards, is constructed for teaching, and you can download the full pack and redo every step yourself.
I built the case this way because most MMM examples online show the stacked decomposition chart and stop. In my experience the chart is the easy part; the places where real projects go wrong are a duplicated week in the spend export, a model chosen because its error is lower on a test it shouldn’t have passed, or a revenue gain presented as if it were profit. If you’re looking for how to build a marketing mix model step by step, the steps below are the ones I’d follow on a real client project, with the fitting step covered in more depth in what is marketing mix modeling, where you can fit one in your browser.
Step 1: Write the brief before you touch the data
Northstar is an invented online homeware brand. Finance has authorised £300,000 for next quarter, and the marketing lead wants to move £30,000 from search to social. Finance’s question is specific: “Does the expected gain justify the uncertainty, and what would we learn before scaling?” That’s a much better starting point than “What’s our ROI?”, because it names a decision, a horizon and a risk, and it tells you the answer could legitimately be “not yet”.
The brief also sets the constraints, which are management decisions rather than model outputs. The total stays at £300k, exactly £30k is reserved for brand presence, and search must stay between £90k and £180k, which means social also lands between £90k and £180k. The current plan is £150k search, £120k social and £30k brand, and the proposed measured shift is £120k search, £150k social and £30k brand. Finance’s contribution margin is 40 percent before advertising (after product and fulfilment costs), and they want the decision rechecked at 30 percent. Fixed overhead, tax and financing are excluded, so a positive contribution after advertising is not the same thing as accounting profit.
If you’re writing a brief for your own business, the MMM measurement plan page has a builder for it. The one sentence I always want before modeling is: “We will use the model to decide ___, over ___, measured by ___, while respecting ___.”
Step 2: Audit the weekly data handoff
The case comes with weekly-inputs-messy.csv, a deliberately corrupted copy of the course’s 104-week practice dataset (weekly revenue, search, social and video spend, and a promotion flag). The data dictionary says each row should be a unique Monday week start, from 2024-01-01 to 2025-12-22, with non-negative spend in pounds and a blank meaning missing rather than zero. Before looking at any corrections, I check row count against unique dates, whether every date is a Monday, missing cells, units and sudden changes in scale. The file has 105 rows for 104 weeks, which is the first clue.
These are the four planted issues and the corrections confirmed by each source owner, from source-corrections.csv:
| Issue | Week | Column | What arrived | Confirmed value | Source of the correction |
|---|---|---|---|---|---|
| Missing export | 2024-02-26 | social_spend | blank | 1,148 | Social owner re-export |
| Unit mismatch | 2024-04-29 | search_spend | 1.827 | 1,827 | Search owner confirms GBP, not thousands |
| Wrong week boundary | 2024-07-30 | week | 2024-07-30 (a Tuesday) | 2024-07-29 | Finance confirms Monday week start |
| Duplicate export | 2024-03-11 | whole row | a second identical record | keep one | Finance confirms duplicate upload |
Each one would have distorted the model in a different way. The blank social week would be read as zero spend by most tools, creating a fake pause in social that the model would try to explain; the search value in thousands is a spend of £1.83 in a file where every other search week sits between about £1,600 and £3,300, so it looks like a channel switched off; the Tuesday date breaks the weekly alignment and can shift carryover by a period; and the duplicated week double-counts both revenue and spend. After the repairs you should have exactly 104 unique Monday rows in the original order, and the pack’s answer-key/verify.py checks every cell against the repaired file rather than just a total that could hide offsetting errors.
What matters as much as the fixes is how you make them. I don’t fill blanks with interpolation or delete rows until the totals look tidy; each repair needs a source and an owner, and the audit log records the original value, the replacement and why it matters. It’s also worth keeping in mind what a clean file doesn’t prove: the audit says nothing about whether an important variable is missing (Northstar’s file has no price or competitor data), whether spend was set in response to demand, or whether the model can separate the channels. The MMM data requirements guide has a fuller checklist, and data cleaning covers the general techniques.
Step 3: Build the marketing mix model, then challenge the review
On a real project, this is where you’d fit the model: transform each channel with adstock and a saturation curve, regress revenue on the transformed spend plus trend, seasonality and the promotion flag, decompose the result into baseline and channel contributions, and validate it on weeks the model hasn’t seen. You can do that on the same 104 weeks in the Python walkthrough, the Excel template or with a library such as Robyn or Meridian. It’s worth knowing before you do that the practice data was generated as an exactly linear function of spend, promotion and a seasonal wave, with no carryover and no saturation, so a well-behaved model should find close to zero adstock and push its saturation parameters to their bounds; that’s a property of the teaching data rather than a finding about Northstar’s channels. The Northstar case deliberately skips the fitting and hands you two invented analyst review cards instead, because the skill finance actually needs from you is judging a model someone else built.
| Review question | Model A: precise-looking | Model B: more cautious |
|---|---|---|
| Held-out revenue RMSE | £4k per week | £6k per week |
| Evaluation design | Random weeks held out; neighboring weeks stay in training | Last 13 weeks held out; transformations fit on training data only |
| Channel schedules | Search and social mostly move together | Same limitation, reported explicitly |
| Controls | Includes same-week website visits with no argument for why | Excludes visits for a total-effect question |
| Calibration | Uses a recent social experiment as both a prior and “independent validation” | Uses the experiment once and checks its spend range and audience |
| Recommendation | Move to the largest social share because the fit is better | Compare constrained plans and stress the social response first |
Model A has the lower error, but the two numbers aren’t comparable, because the models were tested differently. Holding out random weeks lets information leak from the weeks either side, especially when adstock carries spend across weeks or the transformations were tuned on the full dataset, so a random-week RMSE can look better than the model deserves. That doesn’t make a future block automatically right either; Google’s Meridian holdout guidance, for instance, cautions against large contiguous future blocks for its model, so the question to ask is how the transformations and tuning were kept apart from the evaluation. I go deeper into this in MMM model validation.
The other problems with Model A are about causation, not prediction. Website visits might be a mediator that carries part of social’s effect, in which case controlling for them strips credit from the channel you’re trying to measure. Reusing one experiment as a prior and as validation counts the same evidence twice. And because search and social moved together historically, neither model can cleanly separate their effects, which is the multicollinearity problem that no amount of fit fixes. Model B is more honest about its choices, but “more cautious” isn’t the same as causally right: I’d still ask for residual diagnostics, sensitivity to the adstock and saturation settings, the experiment’s scope and the assumptions behind the counterfactual before accepting it.
Step 4: Turn the curves into contribution, under three scenarios
The planning evidence in the case uses response curves that were invented for the exercise, in £ thousands for the whole quarter, with no observations fitted to them. Search incremental revenue is 1000 × S / (100 + S), social is a multiplier × 1200 × X / (140 + X), and brand contributes a fixed £60k for its £30k. Contribution after advertising is the margin times incremental revenue, minus the £300k budget:
The social multipliers of 0.7, 1.0 and 1.3 are stress scenarios, not probabilities or a credible interval, so averaging them into an “expected value” would be making up a distribution. The comparison that matters is always the proposed plan against the current plan under the same assumption. These are the exact numbers for the two plans:
| Margin | Social multiplier | Current plan contribution | Measured shift contribution | Difference |
|---|---|---|---|---|
| 40% | 0.7 (weaker social) | £119.077k | £115.975k | −£3.102k |
| 40% | 1.0 (central) | £185.538k | £190.458k | +£4.919k |
| 40% | 1.3 (stronger social) | £252.000k | £264.940k | +£12.940k |
| 30% | 0.7 (weaker social) | £14.308k | £11.981k | −£2.327k |
| 30% | 1.0 (central) | £64.154k | £67.843k | +£3.689k |
| 30% | 1.3 (stronger social) | £114.000k | £123.705k | +£9.705k |
Three things jump out. First, under the central assumption the shift adds £12.298k of incremental revenue but only £4.919k of contribution at 40 percent margin, so anyone quoting the revenue figure is overstating the benefit by about two and a half times (see breakeven ROAS for why margin has to come in before you compare). Second, the sign flips under the weaker social scenario: the shift loses £3.102k. Third, dropping the margin to 30 percent shrinks every difference by a quarter but doesn’t reverse any of them, because all the plans spend the same £300k, so the margin scales the gap rather than changing its direction. Channel-specific costs, capacity limits or unequal budgets could change that, but none are in the brief.
The explorer below lets you try any feasible allocation, not just the four in the evidence file. Notice where the best search level sits under each scenario: about £122k under the central curves, close to the measured shift, but about £145k (nearly the current plan) if social responds 30 percent worse, and about £106k if it responds 30 percent better.
That’s the real finding of the example. The decision doesn’t hinge on the model’s fit or on which plan ranks first under central assumptions, but on one uncertain number, how strongly social responds at higher spend, and the evidence available can’t pin it down. A small expected gain with a plausible downside is a classic case for testing before committing, which is how MMM scenario planning is meant to be used.
Step 5: Write the decision memo
The case’s memo template forces you to separate four kinds of evidence: an observation (a fact you can see in an input), a model-based calculation (conditional on stated assumptions, with units), an assumption (something the recommendation needs that the evidence doesn’t establish) and independent evidence (what would help from outside these curves). This is one defensible memo, written as the analyst; keeping the current plan, making the shift or proposing a test can each be defended, as long as the reasoning is explicit.
Before sending it, I score the memo against the pack’s six-part rubric (decision and feasibility, data stewardship, evidence categories, economics, uncertainty, actionable learning) and fix anything that calls a prediction causal proof, treats the three scenarios as a calibrated interval, subtracts advertising twice or breaks a budget constraint. Then I ask a colleague to explain the recommendation back to me without the spreadsheet, which is the fastest test I know of whether a memo is clear. The communicating MMM results page has the template as a document you can edit.
Step 6: Design the measurement that would settle it
The memo is only useful if the next step is specific. In Northstar’s case, the uncertain quantity is social’s incremental response at higher spend, so the test should vary social spend across comparable regions, which is what a geo lift test does, and measure contribution rather than platform-reported conversions. The case doesn’t contain the region-level variance, the number of available regions or the cost information needed to set an honest sample size, so the statistical power calculation has to come before the launch date, not after. Once the test reads out, its result goes back into the model as a calibration point, which calibrating MMM with experiments explains.
This is the loop I’d want any marketing mix modeling project to follow: the model narrows the question to the assumption that matters, the experiment tests that assumption, and the next model is better for it.
Redo this marketing mix modeling example yourself
Everything above is in the download, including the messy file and a script that checks your repairs. These are the steps in order, if you want to work through the pack yourself:
Northstar is the case that runs through all 30 lessons of the Vexpower marketing mix modeling course, where each step above gets its own lesson and simulator. If you’d rather start with the mechanics, the MMM practice dataset is the clean version of the weekly file, and the history of marketing mix modeling explains why the method ended up shaped this way. The habit worth taking away is that a marketing mix model earns its keep when it changes a decision, or tells you precisely what you’d need to learn before changing it.
