Causal Churn Retention Attribution — Uplift + DiD 因果用户流失归因与留存优化
Skill-Causal-Churn-Retention-Attribution · 01-因果推断
1. 解决的问题
母婴订阅运营面临流失挽留精准度不足——DR-Learner uplift 模型识别可说服用户(30%),将挽留 ROI 从 1.2x 提升至 4.8x,DiD 三重交互精准分解价格/产品/竞品各因子净贡献,年化节省无效促销成本 30-100 万元
2. 核心算法逻辑
核心问题:用户流失挽留中,"发券给谁"比"发什么券"更重要。naive 模型看到"收到券的用户留存更好"——但这是选择偏差:运营往往只对高价值用户发券,他们本来就不会流失。
3. 业务应用场景
- 业务问题:母婴奶粉/纸尿裤订阅服务季度续订率下滑 12pp,运营默认"发优惠券 = 提升留存",给所有流失预警用户发 8 元券,月均成本 4.2 万元,但实际挽留率仅 18% - 数据要求:用户特征(购买频次、客单价、会员等级、最近一次购买距今天数)、是否收到优惠券(T)、30 天内是否续订(Y),约 500-2000 条历史记录 - 预期产出:每位用户的 CATE 估计 τ(x),圈出 CATE > 阈值的"可说服用户"(约 30%),仅对此群体发券 - 业务价值:发券成本降低 70%,挽留 ROI 从 1.2x 提升至 4.8x,年化节省无效促销成本 30-100 万元
- **业务问题**:Q3 流失率同比暴增 15pp,同期发生了三件事:调价 +8%、主推 SKU 缺货 2 周、竞品推出月度订阅,不知道哪个因素是主因 - **数据要求**:按周/月的用户群流失数据(处理前后各 3 期),能区分受影响用户(暴露组)vs 未暴露用户(对照组) - **预期产出**:价格因子贡献 +6pp,产品缺货贡献 +5pp,竞品贡献 +4pp(含交互项),指导资源优先修复供应链而非降价 - **业务价值**:避免用降价解决供应链问题,单次决策节省促销预算 50-200 万元
4. 输入数据要求
请查看原始代码模板获取输入规格。
5. 输出结果
请查看原始代码模板获取输出规格。
6. 业务价值 / ROI
- ROI 预估:挽留 ROI 从 1.2x 提升至 4.8x(基于 30% 可说服用户比例 + 8 元券成本 + 50 元 LTV 增量估算);年化节省无效促销成本 30-100 万元(视订阅用户体量而定,1 万流失用户规模基准)
- 实施难度:⭐⭐⭐⭐☆(需历史实验数据或近似随机化的发券记录,倾向得分假设较强)
- 优先级:⭐⭐⭐⭐⭐(订阅业务高频决策场景,ROI 杠杆显著)
- 数据门槛:≥300 条含处理/对照的留存记录,处理率建议 10%-70%(极端倾向得分会导致方差爆炸)
- 关键风险:违反可忽略性假设(运营有未观测选择逻辑)→ 可结合 RCT 验证;DiD 平行趋势需在 Post 期前 3 期图形验证
7. 代码模板
代码块数量:1 · 路径:未检测到
import numpy as np
from sklearn.linear_model import LogisticRegression, LinearRegression
from sklearn.model_selection import cross_val_predict
from sklearn.preprocessing import StandardScaler
np.random.seed(42)
# ─────────────────────────────────────────────
# 数据生成:500个母婴订阅用户
# ─────────────────────────────────────────────
def generate_baby_subscription_data(n=500):
"""生成母婴订阅用户模拟数据"""
# 用户特征
recency = np.random.exponential(30, n) # 最近一次购买距今(天)
frequency = np.random.poisson(5, n) + 1 # 过去6个月购买次数
monetary = np.random.lognormal(4.5, 0.5, n) # 平均客单价(元)
membership = np.random.choice([0, 1, 2], n, p=[0.5, 0.3, 0.2]) # 会员等级
X = np.column_stack([recency, frequency, monetary, membership])
# 倾向得分:高价值用户更容易收到券(运营bias)
propensity_logit = -1.0 + 0.02 * frequency - 0.003 * recency + 0.3 * membership
propensity = 1 / (1 + np.exp(-propensity_logit))
T = (np.random.random(n) < propensity).astype(int)
# 潜在结果:CATE 异质性(recency 大、frequency 低的用户对券更敏感)
cate_true = 0.15 - 0.002 * recency + 0.02 * frequency + 0.05 * membership
cate_true = np.clip(cate_true, -0.05, 0.4)
# 基础留存概率
base_retention = 0.3 + 0.02 * frequency - 0.003 * recency + 0.1 * membership
base_retention = np.clip(base_retention, 0.05, 0.95)
Y = (np.random.random(n) < (base_retention + T * cate_true)).astype(int)
return X, T, Y, cate_true, propensity
# ─────────────────────────────────────────────
# Phase 1: S-Learner 基础 Uplift(基准方法)
# ─────────────────────────────────────────────
def s_learner_uplift(X, T, Y):
"""S-Learner: 将T作为特征,预测处理/对照的差值"""
XT = np.column_stack([X, T])
model = LogisticRegression(max_iter=1000, C=0.5)
model.fit(XT, Y)
X1 = np.column_stack([X, np.ones(len(X))])
X0 = np.column_stack([X, np.zeros(len(X))])
uplift = model.predict_proba(X1)[:, 1] - model.predict_proba(X0)[:, 1]
return uplift
# ─────────────────────────────────────────────
# Phase 2: DR-Learner 双重鲁棒 Uplift
# ─────────────────────────────────────────────
def dr_learner_uplift(X, T, Y, n_folds=5):
"""
DR-Learner: 双重鲁棒元学习器8. 论文来源
未自动抽取;请查看原始 Skill 卡片。