KOL ROI 因果归因(网红/达人投放效果的真实增量测算)
Skill-KOL-ROI-Causal-Attribution · 15-营销投放分析
causalexperimentrecommendation广告与投放推荐与搜索WF-B 广告优化WF-D 选品扫描WF-G Listing内容优化WF-L 内容营销增长
年化 ROI30 万/月
实现难度⭐⭐⭐☆☆
业务视角
适用角色CMO / 营销负责人 · 广告优化师 · CEO
适用平台Amazon + TikTok + Meta + KOL 四渠道 · Prime Day / Black Friday 预算前置
什么情况下用同时跑 Amazon 广告/TikTok/网红投放/邮件,不知道整体预算怎么分配最高效;网红投放花了大钱但不知道带来多少真实 GMV
成功是什么样的建立全渠道营销归因模型(MMM),每个渠道真实 ROI 可量化,大促前做预算优化模拟
业务痛点
1. 解决的问题
月 KOL 投放 30 万元,naive 归因显示 ROAS 3.5,但无法区分「因 KOL 才购买」和「本来就会买顺路点了链接」——PSM+DiD 因果归因将头部 KOL iROAS 从 4.2 修正为 1.8,将 30 万预算转向腰部 KOL 后年化增量 GMV 提升 44%
2. 核心算法逻辑
核心思想:KOL 投放的传统 ROI 计算(曝光量 × 转化率 × 客单价 / 投放费用)存在根本性缺陷——它无法区分「因为看了这条视频才购买」和「本来就会购买,顺路点了链接」。因果归因框架用反事实推断计算 KOL 投放的真实增量(ITE/LATE),消除自我选择偏差。
3. 业务应用场景
场景 A:TikTok KOL 矩阵投放效果评估(大品类分析)
- 业务痛点:品牌同时合作 50 个 TikTok KOL(头部 3 个 + 腰部 15 个 + 尾部 32 个),总投入 100 万元/月,naive GMV 归因显示 ROI = 3.5,但无法判断哪类 KOL 真正带来了增量 - 分析路径: 1. 获取 TikTok 平台的随机实验数据(Brand Lift Study,平台提供) 2. 对于无实验数据的 KOL,用 PSM 匹配「看过视频的用户」和「未看过但特征相似的用户」 3. 对每个 KOL 估计 iROAS - 结论示例: - 决策:将 30 万预算从头部 KOL 转移到腰部 KOL,总 iROAS 从 1.9 提升到 2.6
场景 B:小红书种草到 Amazon 购买的跨平台归因
4. 输入数据要求
请查看原始代码模板获取输入规格。
5. 输出结果
请查看原始代码模板获取输出规格。
6. 业务价值 / ROI
- TikTok Brand Lift Study 可直接申请(需达量门槛),低难度
- PSM + DiD 分析:中等(需匹配数据,但 Python 工具链成熟)
- 跨平台归因(小红书→Amazon):较难(无 ID 打通,需 RDD 等间接方法)
7. 代码模板
代码块数量:6 · 路径:未检测到
from dataclasses import dataclass
import numpy as np
from scipy import stats
@dataclass
class KOLCampaign:
kol_id: str
spend: float
naive_gmv: float
exposed_users: int
control_users: int
exposed_cvr: float
control_cvr: float
aov: float
def estimate_incremental_roas(campaign: KOLCampaign) -> dict:
"""
PSM 配对后的双样本因果 iROAS 估计。
假设 exposed/control 已经过倾向得分匹配,组间特征平衡。
"""
delta_cvr = campaign.exposed_cvr - campaign.control_cvr
se = np.sqrt(
campaign.exposed_cvr * (1 - campaign.exposed_cvr) / campaign.exposed_users
+ campaign.control_cvr * (1 - campaign.control_cvr) / campaign.control_users
)
z_stat = delta_cvr / se
p_value = 2 * (1 - stats.norm.cdf(abs(z_stat)))
incremental_gmv = delta_cvr * campaign.exposed_users * campaign.aov
i_roas = incremental_gmv / campaign.spend if campaign.spend > 0 else 0.0
attribution_fraction = incremental_gmv / campaign.naive_gmv if campaign.naive_gmv > 0 else 0.0
return {
"kol_id": campaign.kol_id,
"naive_roas": round(campaign.naive_gmv / campaign.spend, 2),
"i_roas": round(i_roas, 2),
"incremental_gmv": round(incremental_gmv),
"attribution_fraction": round(attribution_fraction, 3),
"delta_cvr": round(delta_cvr, 4),
"p_value": round(p_value, 4),
"significant": p_value < 0.05,
}
def rank_kol_portfolio(campaigns: list[KOLCampaign]) -> list[dict]:
results = [estimate_incremental_roas(c) for c in campaigns]
results.sort(key=lambda x: x["i_roas"], reverse=True)
return results
# === 测试用例(模拟头部/腰部/尾部 KOL)===
campaigns = [
KOLCampaign("KOL-TOP-001", spend=50000, naive_gmv=210000, exposed_users=50000,
control_users=50000, exposed_cvr=0.042, control_cvr=0.038, aov=1000),
KOLCampaign("KOL-MID-007", spend=20000, naive_gmv=62000, exposed_users=25000,
control_users=25000, exposed_cvr=0.031, control_cvr=0.020, aov=800),
KOLCampaign("KOL-TAIL-023", spend=5000, naive_gmv=12000, exposed_users=8000,
control_users=8000, exposed_cvr=0.028, control_cvr=0.019, aov=750),
]
results = rank_kol_portfolio(campaigns)
for r in results:
print(f"{r['kol_id']}: naive_ROAS={r['naive_roas']} | iROAS={r['i_roas']} | "8. 论文来源
未自动抽取;请查看原始 Skill 卡片。