Causal Mediation Analysis — Decomposing "Why It Works
Skill-Mediation-Causal-Mechanism-Analysis · 01-因果推断
causalexperimentforecastingoptimizationrecommendation客服与VOC推荐与搜索WF-C 客服分诊WF-G Listing内容优化WF-H 复购增长
年化 ROI10-30万
实现难度⭐⭐☆☆☆
业务优先级⭐⭐☆☆☆
业务视角
适用角色增长负责人 / CMO · 数据分析师 · 广告优化师
适用平台Amazon · TikTok Shop · Meta Ads · DTC 独立站
什么情况下用广告预算花了,但不确定哪个渠道真的带来新客;做了大促,不知道销量增长是促销效果还是季节规律
成功是什么样的能区分「真实增量」和「自然购买」,砍掉虚假归因渠道后同等预算 ROI 提升 20-40%
业务痛点
1. 解决的问题
核心思想:中介分析回答"为什么"——一个干预(如推荐算法更新)通过什么机制影响了结果(如转化率)。它将总效应分解为
2. 核心算法逻辑
核心思想:中介分析回答"为什么"——一个干预(如推荐算法更新)通过什么机制影响了结果(如转化率)。它将总效应分解为:
3. 业务应用场景
业务问题:产品团队上线了新的推荐算法(基于用户行为的协同过滤 → 基于内容的混合推荐),全站转化率提升了2%。但产品经理想知道:这2%是通过什么路径实现的?是点击率提升了?还是用户浏览深度增加了?还是客单价变了?
中介变量选择: - $M_1$ = 点击率(CTR) - $M_2$ = 平均浏览页面数 - $M_3$ = 平均客单价
应用流程: 1. 总效应估计:对比算法上线前后,处理组(被推荐商品)vs 对照组(未被推荐商品)的转化率变化 2. 逐个中介分析:对每个中介变量M,估计NDE和NIE 3. 机制排序:比较各中介的间接效应大小,找出主要驱动机制
4. 输入数据要求
请查看原始代码模板获取输入规格。
5. 输出结果
请查看原始代码模板获取输出规格。
6. 业务价值 / ROI
- 数据要求:需要同时观测干预、中介和结果三个变量
- 技术门槛:低,核心是OLS回归的组合
- 主要挑战:选择合理的中介变量 + 论证识别假设(无未观测混杂)
- 从"知道有效"到"知道为什么有效":这是从执行层到策略层的跃迁
- 方法极简单:两个OLS回归即可,但洞察极深刻
- 通用性最强:任何A/B测试、政策评估、算法更新后都应该做机制分解
7. 代码模板
代码块数量:1 · 路径:未检测到
"""
Causal Mediation Analysis — 因果中介效应分析
用于分解干预的总效应为直接效应和间接效应
支持:经典中介分析、多重中介分析、Surrogate Index
"""
import numpy as np
import pandas as pd
from sklearn.linear_model import LinearRegression
import warnings
warnings.filterwarnings('ignore')
# ==================== 中介分析核心实现 ====================
class MediationAnalysis:
"""因果中介分析器"""
def __init__(self, method='parametric'):
"""
初始化中介分析器
Args:
method: 'parametric' (基于回归) 或 'bootstrap'
"""
self.method = method
self.a_coef = None # T → M 的效应
self.b_coef = None # M → Y 的效应(控制T)
self.c_prime = None # T → Y 的直接效应(控制M)
self.results = {}
def fit(self, T, M, Y, X_controls=None):
"""
拟合中介分析模型
Args:
T: 干预变量 (n_samples,)
M: 中介变量 (n_samples,) — 可扩展为多重中介
Y: 结果变量 (n_samples,)
X_controls: 控制变量 (n_samples, n_controls)
"""
T = np.array(T).ravel()
M = np.array(M).ravel()
Y = np.array(Y).ravel()
n = len(T)
# 构建特征矩阵
if X_controls is not None:
X_controls = np.array(X_controls)
if X_controls.ndim == 1:
X_controls = X_controls.reshape(-1, 1)
# ========== 模型1: T → M (路径a) ==========
if X_controls is not None:
X_a = np.column_stack([T, X_controls])
else:
X_a = T.reshape(-1, 1)
model_a = LinearRegression()
8. 论文来源
未自动抽取;请查看原始 Skill 卡片。