Skip to content

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

2 Commits
 
 
 
 
 
 
 
 
 
 

Repository files navigation

PULSE//MMM

A marketing-mix model that runs in a browser tab. Drop in a weekly spend-per-channel history and it measures what each channel actually contributed, what the next dollar earns, and where to shift budget — using real MMM techniques (adstock carryover, diminishing-returns saturation, least-squares fit), all computed locally.

No install. No Python or R. No AI. No uploads — your spend data never leaves the page.

▶ Open the tool · or download index.html (right-click → Save Link As) and open it offline.

Why

Serious MMM tools — Meta's Robyn, Google's Meridian, PyMC-Marketing — are excellent and also a project: a language runtime, a dependency tree, and a data scientist to drive them. Most marketing teams never get past that setup cost, so they keep making budget-split decisions off last-click attribution, which systematically undercredits anything that isn't a bottom-funnel click.

This is the 80% version you can actually run on a Tuesday: one file, one CSV, an answer in about ten seconds — and every number shows the formula that produced it.

Quick start

  1. Open the live tool (or download index.html).

  2. Click Try it: sample 52-week account to see the whole thing work before touching your own data.

  3. Build your CSV — a wide table, one row per week:

    week,meta_spend,google_spend,tv_spend,revenue
    2025-08-25,2036.97,2317.94,0.00,13408.40
    2025-09-01,2160.64,2294.00,0.00,14792.42
    

    Weekly spend totals come from each platform's export; revenue or conversions come from your store or CRM. Most teams assemble this in a spreadsheet in about ten minutes. Daily rows work too — they're aggregated to weeks automatically, so you need roughly six months of days for a usable fit.

  4. Drop it in, confirm the auto-detected results column, and read the verdicts.

What you get

Output What it tells you
Model fit (R² + holdout error) Whether to trust the split at all — the tool grades itself trustworthy / directional / too weak to act on before showing conclusions
Base vs. media-driven How much of your revenue would happen anyway versus what advertising actually moved
Contribution per channel Modeled share of results each channel drove — not last-click credit
Next-dollar return What one more dollar per week earns at your current spend level, carryover included — the number that should drive budget decisions
Carryover % How much of a week's impact lands in later weeks (why TV and video look worse than they are in last-click)
Verdicts INVEST / HOLD / TRIM / UNPROVEN per channel, with the reasoning and the formula trace
Reallocation Concrete shifts sized at a safe 10%-per-round step, with the expected weekly gain

How the model works

For each channel, spend is transformed twice before fitting:

  1. Adstock (carryover): z_t = spend_t + θ · z_(t−1) — this week's advertising keeps working next week. θ is searched over a grid per channel.
  2. Saturation (diminishing returns): effect = β · z^α with α ≤ 1 — the tenth thousand dollars does less than the first.
  3. Fit: θ and α are chosen per channel by coordinate descent on R², then β is solved by ordinary least squares with a non-negativity pass (channels that come back negative are dropped rather than reported as harmful). θ is searched over {0, 0.2, 0.4, 0.6, 0.8}, so the reported carryover is quantised to those steps.
  4. Marginal return: β·α·z̄^(α−1) ÷ (1−θ) — the derivative at your typical spend level, which is what "should I add budget here?" actually depends on.

Every one of these numbers is visible per channel under show the math.

Honest limitations

This is a lite model, and it says so in the UI:

  • Flat spend can't be measured. A channel funded at the same amount every week has nothing to correlate against; it's marked UNPROVEN, not given a fake number.
  • It reads correlation. A channel that only runs during your peak season will look better than it is.
  • Overlapping channels blur. Brand search and retargeting chase the same demand signal, and the model may split credit between them arbitrarily.
  • It needs history. Six-plus months of weekly rows; below ~24 periods the tool warns you explicitly.
  • The base/media split can break. If your channels are credited with more than your total results — which happens when there's little organic baseline, or spend tracks results too closely — the tool says so and marks the split unusable rather than showing an impossible number. Channel rankings stay valid.

Use it for direction and budget splits, then confirm with holdout tests (turn a channel off in one region for a few weeks) — not as courtroom-grade attribution.

Companion tool

PULSE//AUDIT is the bottom-up half: it audits an individual ad account (Meta, Google, TikTok, LinkedIn) and tells you which ads and keywords to scale, pause, or kill. Same philosophy — one file, no AI, transparent rules. Use MMM to set the budget split across channels; use AUDIT to spend each channel's budget well.

Contributing

Issues and PRs welcome. It's one dependency-free HTML file: fitModel() holds the adstock/saturation/OLS logic, runModel() turns coefficients into verdicts. Good contributions: ridge regularization for correlated channels, seasonality/holiday controls, a scenario slider for "what if I moved 20%?", confidence intervals via bootstrap.

License

MIT

About

Marketing-mix modeling in a browser tab. Adstock + saturation + least squares on your weekly spend data — no install, no Python, no AI, nothing uploaded.

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages