webtracking.org
tools

Compare attribution models on your own paths: last click to Markov and Shapley

Compare attribution models on your own conversion paths — last click, position-based, time-decay, Markov removal effect, and Shapley — free and in-browser.

last verified 2026-07-18

Every attribution report is an opinion wearing a number. Last click says brand search closes everything; a vendor’s “data-driven” model says display deserves triple the credit; nobody can explain the gap because nobody can see the math. The Attribution Model Simulator makes the gap visible: paste your conversion paths once and watch seven models — last click, first click, linear, position-based 40/20/40, time-decay, Markov removal effect, and Shapley value — divide the same conversions differently, side by side, with the exact algorithm behind each column documented on the page.

It is built for measurement managers who need to defend (or challenge) a model choice, marketers deciding whether a channel’s credit is real or an artifact of the rule, and data engineers who want reference implementations they can reproduce in a warehouse. Everything runs client-side in your browser; paths are parsed and scored locally and nothing is sent anywhere.

What it does

You provide journeys in a simple text format — one path per line, channels separated by >, then a conversion count and an optional non-converting count:

Paid Search > Email > Direct, 120, 340
Organic Search, 210, 1900

Press Run models and the tool renders:

  • A summary line: total paths, unique channels, total conversions, and total non-converting journeys. Every model column is efficient — it sums to total conversions — so the Total row is a built-in sanity check.
  • A credits table with one row per channel and one column per model: last click, first click, linear, position 40/20/40, time-decay (labelled with the half-life you set), Markov removal, and Shapley.
  • Bar-chart panels, one per model, so you can eyeball how the ranking of channels shifts as the rule changes.
  • Markov diagnostics inside the model’s explainer: the baseline conversion probability P(CONV | START) for your dataset (to four decimals) and each channel’s removal effect, sorted largest first.

Malformed lines don’t kill the run — they’re skipped and listed with line numbers and the reason (“no channels before the first comma”, “missing or invalid conversions count”, and so on), and the valid paths still score.

How it works

The engine (attribution.js) is a dependency-free module that implements the algorithms published in the Attribution Models standard; it runs in the browser and in Node, so the same code that renders the page also runs the test suite.

Parsing. Each line is split with a real CSV splitter that honours double-quoted fields (with "" as a literal quote), so a channel named "Acme, Inc. Referral" survives intact. The first field is split on > into the ordered channel list. A leading header row is skipped only when its first field is exactly a header word (path, journey, channels, touchpoints, singular or plural) and its count column isn’t numeric — a data line that merely looks header-ish is surfaced as an error instead of silently swallowed.

Rule-based models share one allocator: a weight function returns per-touch weights summing to 1, and each converting path distributes its conversion count by those weights. Non-converting paths carry no credit here. The specifics:

  • Last / first click: weight 1 on the final or first touch.
  • Linear: 1/n per touch.
  • Position-based 40/20/40: 40% first, 40% last, 0.20/(n-2) per middle touch — with the edge cases collapsing by design (a 1-touch path gets 100%, a 2-touch path splits 50/50).
  • Time-decay: raw_i = 2^(−(n−i)/h) with 1-based position i and half-life h in steps, then normalized per path. Because this input format carries touch order but no timestamps, decay is by position: a touch h steps before the last one gets half its weight.

Markov removal effect is the one model that uses your non-converting counts. Journeys become a first-order chain with states START, one per channel, CONV, and NULL (reserved state keys are prefixed with a NUL byte, so a user channel can never collide with them). Transition probabilities are estimated from all paths weighted by their counts; converting paths end in CONV, non-converting in NULL. The baseline conversion probability is solved as an absorbing-chain fixed point by Gauss–Seidel iteration (tolerance 1e-9, capped at 10,000 sweeps). To score a channel the solver “removes” it by pinning its state value at zero — equivalent to redirecting every transition into it to NULL — and re-solves. The relative drop is the removal effect, clamped to [0, 1], and credit is allocated proportionally: credit(c) = total_conversions × RE(c) / Σ RE.

Shapley value uses the standard’s order-agnostic simplification: a coalition’s value v(S) is the total conversions of paths whose channel set is contained in S. The engine builds v over all 2^n coalitions with a subset-sum (zeta) transform, then computes each channel’s exact Shapley value — its marginal contribution averaged over every coalition-formation order. Because enumeration is exact, the tool refuses datasets with more than 12 unique channels and tells you to collapse rare channels into an Other bucket.

How to use it

  1. Open the Attribution Model Simulator and click Load sample data to see the format on a realistic 11-path dataset, or paste your own paths.
  2. Alternatively click Upload CSV… — first column is the path (quote it if a channel name contains a comma), then conversions, then an optional non-converting count. The file is read with the browser’s FileReader; it is never uploaded.
  3. Set the time-decay half-life (default 2 steps; minimum 0.1). Changing it re-runs the models automatically once results are on screen.
  4. Click Run models, or press Ctrl/Cmd + Enter in the textarea.
  5. Read the table across a row: a channel whose credit swings hard between last click and Markov is the one your model choice is actually deciding about. Expand the “How each model works” panels for the formula behind any column, including this run’s Markov baseline and removal effects.
  6. Clear resets the input and results.

To get path data in the first place: GA4 and Adobe both expose path-style reporting, or you can build paths from raw events in your warehouse — see BigQuery for web analytics and sessionization for how touch sequences get stitched together, and channel grouping for deciding what a “channel” even is before you paste.

Limitations

  • Order, not timestamps. The input format has no dates, so time-decay halves by touch position, not days. The published standard defines the same exponential over days; with real timestamps, substitute age in days for the step count.
  • Shapley is order-agnostic and capped. v(S) looks at channel sets, not sequences, and exact enumeration stops at 12 unique channels.
  • Markov is first-order. Transitions depend only on the current state, and pathological inputs (one channel repeated thousands of times in a single path) can hit the 10,000-sweep cap — the engine logs a console warning rather than pretending the result is exact.
  • Rule-based models and Shapley ignore non-converting paths. Only Markov learns from them, so the non-converting column changes exactly one column of the table.
  • Attribution is not incrementality. All seven models are accounting conventions over observed paths; none answers the causal “what if we cut this budget?” question. That boundary is the core of attribution fundamentals.
  • Garbage paths, confident garbage. The tool scores whatever paths you give it; identity stitching and campaign tagging quality upstream matter more than model choice.

FAQ

Why do the models disagree so much on the same data? Because they encode different assumptions: last click credits closers, first click credits openers, Markov credits load-bearing states, Shapley credits marginal contribution across coalitions. The spread across models is the honest uncertainty band — budget against the range, not one column.

Which model is “correct”? None. Each column is reproducible and internally consistent, but attribution divides observed credit; it cannot prove a channel caused conversions. Use the range to spot channels whose value is model-dependent, then test those with experiments.

Do I need non-converting path counts? Only for Markov. Without them the chain sees no NULL transitions and its removal effects lean on converting paths alone. The other six models produce identical numbers with or without the third column.

Why did Shapley refuse to run? Your dataset has more than 12 unique channels; exact enumeration over 2^n coalitions gets expensive fast. Collapse rare channels into an Other bucket and re-run — the warning says exactly this, and the other six models still compute.

Is my data uploaded anywhere? No. Parsing, the Markov solver, and the Shapley enumeration all run in your browser; CSV files are read locally with FileReader. The page works offline once loaded.