Multi-Touch Attribution Model
7-Channel Integration
ConversionOS includes a data-driven multi-touch attribution model that distributes conversion credit across all marketing channels. Replaces last-click with ML-based attribution.
Supported Channels
| # | Channel | Data Source | Attribution Weight Method |
|---|---|---|---|
| 1 | Paid Search | Google Ads API | Click-weighted Shapley |
| 2 | Paid Social | Meta/LinkedIn APIs | View-through + click |
| 3 | Organic Search | GA4 / Search Console | Session-based |
| 4 | SFMC engagement data | Click attribution | |
| 5 | Direct Mail | Match-back via Adstra | Household-level match |
| 6 | Call Center | IVR + agent disposition | Inbound call attribution |
| 7 | Organic Social | UTM-tagged traffic | Session-based |
Attribution Methodology
Data-Driven Attribution (Shapley Values)
ConversionOS uses Shapley value attribution — a game-theory approach that assigns credit based on each channel's marginal contribution:
import itertools
from collections import defaultdict
def shapley_attribution(conversion_paths, channels):
"""Calculate Shapley values for channel attribution."""
shapley_values = defaultdict(float)
n = len(channels)
for channel in channels:
for subset_size in range(n):
for subset in itertools.combinations(
[c for c in channels if c != channel], subset_size
):
subset_set = set(subset)
# Conversion rate WITH this channel
with_channel = conversion_rate(
conversion_paths, subset_set | {channel}
)
# Conversion rate WITHOUT this channel
without_channel = conversion_rate(
conversion_paths, subset_set
)
# Shapley weight
weight = (
factorial(subset_size) *
factorial(n - subset_size - 1)
) / factorial(n)
shapley_values[channel] += weight * (
with_channel - without_channel
)
return dict(shapley_values)
Path Construction
-- Build conversion paths from touchpoint data
WITH touchpoints AS (
SELECT
user_id,
channel,
touchpoint_timestamp,
ROW_NUMBER() OVER(
PARTITION BY user_id ORDER BY touchpoint_timestamp
) AS touch_order
FROM `project.conversionos.unified_touchpoints`
WHERE touchpoint_timestamp >= DATE_SUB(CURRENT_DATE(), INTERVAL 90 DAY)
),
paths AS (
SELECT
user_id,
STRING_AGG(channel, ' > ' ORDER BY touch_order) AS conversion_path,
COUNT(*) AS path_length,
MAX(CASE WHEN converted = 1 THEN 1 ELSE 0 END) AS converted
FROM touchpoints t
LEFT JOIN conversions c USING(user_id)
GROUP BY user_id
)
SELECT * FROM paths;
Incrementality Validation
Attribution models tell you correlation. Incrementality testing tells you causation:
- Geo-lift tests: Holdout geographic regions from specific channels
- PSA holdouts: Serve public service ads to control group
- Platform lift studies: Google/Meta native conversion lift measurement
- Calibration: Use incrementality results to adjust attribution weights
Output Integration
Attribution results flow into:
- Budget allocation models — Shift spend toward channels with highest incremental ROAS
- Reporting dashboards — Replace last-click reports with data-driven attribution
- Model features — Attribution-aware channel engagement features improve propensity models