Every marketing team runs campaigns across multiple channels simultaneously. Every month they ask the same question: which channels are actually driving conversions, and how much budget should each get?
The answer depends entirely on which attribution model you trust — and most teams are using the wrong one.
Last Touch attribution was the default in Google Universal Analytics for years. It gives 100% of conversion credit to the final channel a user touched before converting. It's simple, easy to explain, and wrong.
In a world where the average customer journey spans 3–5 touchpoints before converting, crediting only the last one ignores everything that built awareness, drove consideration, and kept the brand top of mind. It rewards closers and punishes the channels that started the conversation.
This project quantifies exactly how much that matters.
Synthetically generated customer journey data — 50,000 users, 169,742 touchpoints, calibrated to real multi-channel conversion benchmarks.
| Metric | Value |
|---|---|
| Total users | 50,000 |
| Total touchpoints | 169,742 |
| Conversions | 1,772 (3.5%) |
| Total attributed revenue | $160,418 |
| Average order value | $90.53 |
| Median journey length | 3 touchpoints |
Channels: Paid Search, Organic, Email, Social, Display, Direct
Journey design: Conversion probability increases with journey length (longer journeys signal higher intent). Channel conversion rates are calibrated to industry benchmarks — Direct and Email convert highest, Display lowest.
| Model | Logic |
|---|---|
| First Touch | 100% credit to the first channel in the journey |
| Last Touch | 100% credit to the channel immediately before conversion |
| Linear | Equal credit split across every touchpoint |
| Time Decay | More credit to touchpoints closer to conversion (half-life: 7 days) |
| Channel | First Touch | Last Touch | Linear | Time Decay |
|---|---|---|---|---|
| Paid Search | 26.8% | 27.7% | 26.5% | 26.4% |
| 21.6% | 20.9% | 20.8% | 21.0% | |
| Organic | 18.5% | 16.9% | 19.2% | 18.6% |
| Social | 14.5% | 14.5% | 13.9% | 14.2% |
| Direct | 10.2% | 10.9% | 10.8% | 11.0% |
| Display | 8.3% | 9.0% | 8.9% | 8.8% |
| Channel | First Touch | Last Touch | Linear | Time Decay |
|---|---|---|---|---|
| Paid Search | $26,800 | $27,700 | $26,500 | $26,400 |
| $21,600 | $20,900 | $20,800 | $21,000 | |
| Organic | $18,500 | $16,900 | $19,200 | $18,600 |
| Social | $14,500 | $14,500 | $13,900 | $14,200 |
| Direct | $10,200 | $10,900 | $10,800 | $11,000 |
| Display | $8,300 | $9,000 | $8,900 | $8,800 |
Compared to Linear attribution, Last Touch:
- Undervalues Organic by $2,300 — Organic consistently initiates journeys but rarely closes them, so Last Touch strips it of credit it genuinely earned
- Overvalues Paid Search by $1,200 — Paid Search appears frequently at the end of journeys, collecting credit for conversions that Organic or Email built
Across a $100K budget, that's a $2,300 misallocation away from a channel doing real work. Scale that to $1M and it's $23,000 misdirected every month.
Model choice is a budget decision. Make it deliberately.
- Retire Last Touch as your default. It rewards closers and punishes the channels that build the pipeline.
- Use Linear or Time Decay as a starting baseline. They account for the full journey without requiring behavioural assumptions about recency.
- Pair attribution with incrementality testing. Attribution tells you correlation — incrementality tells you causation. You need both.
- Re-run this comparison quarterly. Channel mix shifts, and so does attribution.
- Python — pandas, NumPy, matplotlib
- Analysis — Jupyter Notebook
marketing-attribution-analysis/
├── analysis.ipynb # Full analysis with all models and charts
├── README.md # This document
└── output/
├── fig_eda.png # Journey length + channel volume
├── fig_attribution_comparison.png # Revenue % by channel and model
├── fig_budget_divergence.png # Budget allocation across models
└── fig_lt_vs_linear_delta.png # Cost of trusting Last Touch