Multi-touch attribution system for B2B SaaS GTM teams. Compares last-touch, linear, Markov chain, and Shapley value models — then uses the Claude API to auto-generate executive narratives, budget reallocation recommendations, and answer natural language questions about channel performance.
Most B2B GTM teams default to last-touch attribution, which systematically over-credits bottom-funnel channels and starves mid-funnel investment. This engine quantifies that distortion and surfaces it in a format an exec can act on.
- 4 attribution models compared side-by-side: last-touch, linear, Markov chain, Shapley value
- Markov chain removal-effect analysis — measures each channel's true incremental contribution
- Shapley value fair-credit allocation — game-theoretically optimal attribution
- Claude API insight generation — auto-writes channel narratives and budget reallocation recommendations
- Natural language Q&A panel — ask freeform questions, get data-grounded answers
- Snowflake-native with CSV demo mode (no credentials required to explore)
Synthetic Data Generator
│
▼
Snowflake (TOUCHPOINTS table)
│
▼
Python Attribution Models
├── Last Touch
├── Linear
├── Markov Chain (removal effect)
└── Shapley Value
│
▼
Claude API (claude-sonnet-4-6)
├── Channel performance narrative
├── Budget reallocation JSON
└── NL Q&A
│
▼
Streamlit Dashboard (4 tabs)
git clone https://github.com/Mohona19/gtm-attribution-engine
cd gtm-attribution-engine
python -m venv venv && source venv/bin/activate
pip install -r requirements.txt
cp .env.example .env
# Add your ANTHROPIC_API_KEY (Snowflake credentials optional)
# Generate synthetic data
python data/generate_synthetic_data.py
# Launch dashboard (runs in CSV demo mode without Snowflake)
streamlit run app/streamlit_app.pygtm-attribution-engine/
├── data/
│ ├── generate_synthetic_data.py # Generates 5k journeys, ~18k touchpoints
│ └── sample_data.csv # 500-row sample for demo mode
├── snowflake/
│ ├── setup_schema.sql # DDL + views
│ └── load_data.sql # COPY INTO + validation queries
├── models/
│ ├── attribution_last_touch.py
│ ├── attribution_linear.py
│ ├── attribution_markov.py
│ └── attribution_shapley.py
├── insights/
│ ├── claude_insight_generator.py # All Claude API calls
│ └── prompt_templates.py # Prompt constants
├── app/
│ ├── streamlit_app.py # Main dashboard entry point
│ └── components/ # Reusable chart & panel components
├── notebooks/
│ └── 01_attribution_exploration.ipynb
├── .env.example
├── requirements.txt
└── DESIGN_NOTES.md # Technical decisions & tradeoffs
Screenshot of Tab 1 will go here
Loom recording link will go here
See DESIGN_NOTES.md for rationale on model selection, LLM prompt architecture, Snowflake schema design, and what I'd build next.
| Layer | Technology |
|---|---|
| Data warehouse | Snowflake |
| Data generation | Python / NumPy |
| Attribution models | Python / pandas |
| AI insight layer | Anthropic Claude API |
| Dashboard | Streamlit + Plotly |
| Environment | python-dotenv |