Python uplift modeling 的 python 实现

2次阅读

uplift modeling需建模因果效应p(y=1|x,t=1)−p(y=1|x,t=0),tlearner更鲁棒,用两个分类器分别拟合处理组和对照组再相减;slearner将t作为特征拼接,需构造交互项防高估;causalml中uplifttreeclassifier要求y、t均为int型0/1,qini系数需按uplift排序后计算。

Python uplift modeling 的 python 实现

怎么用 python 做 uplift modeling(不是分类,也不是回归)

Uplift modeling 的目标不是预测“用户会不会买”,而是预测“用户因为收到这个营销动作而多大可能买”——也就是干预的因果效应。直接套用 sklearnLogisticRegressionXGBClassifier 会错:它们默认建模的是 P(Y=1 | X),而不是 P(Y=1 | X, T=1) − P(Y=1 | X, T=0)。必须显式建模处理组和对照组的响应差异。

Slearner 和 Tlearner:选哪个?参数怎么调?

两种最常用、可直接用 Python 实现的基础方法。Slearner 把处理变量 T 当作普通特征拼进特征矩阵,用一个模型拟合 Y ~ X + T;Tlearner 分别训练两个模型:Y[T=1] ~ XY[T=0] ~ X,再相减得 uplift。实际中 Tlearner 更鲁棒,尤其当两组样本分布差异大时;Slearner 对 T 的系数敏感,容易高估 uplift(尤其当基础响应率高时)。

  • Tlearner 推荐用 lightgbm.LGBMClassifiersklearn.ensemble.RandomForestClassifier,两棵树都设 class_weight='balanced',避免对照组样本多导致模型忽略处理组信号
  • Slearner 若坚持用,务必在特征工程阶段对 T 做交互项(如 X_i * T),否则模型几乎学不到异质性;sklearnPolynomialFeatures 可辅助生成,但注意维度爆炸
  • 两者的预测输出都是概率差值,但 Tlearner 的 uplift = model_t.predict_proba(X)[:, 1] - model_c.predict_proba(X)[:, 1],必须用 predict_proba,不能用 predict

uplift_tree_classifier 报错 “ValueError: y must be binary” 怎么修?

这是 causalml 库里最常踩的坑:它不接受 [0, 1]y,而要求 y 是二值但标签名必须是字符串或类别型(如 ['control', 'treatment'])。更隐蔽的是,它还强制要求 T(干预变量)也必须是二值且 dtype 为 int,但值只能是 01(不能是 -1/1True/False)。

  • 检查 y.dtypeT.dtype,统一转成 intT = T.astype(int)y = y.astype(int)
  • 如果 y[0, 1] 但报错,试试 y = pd.Categorical(y).codes 或显式映射:y = np.where(y == 1, 'treated', 'control')(取决于你用的是哪个 uplift tree 实现)
  • causalmlUpliftTreeClassifier 不支持 sample_weight,若需加权,得先用 sklearn.utils.resample 手动过采样

评估 uplift 模型不能只看 AUC,Qini 系数怎么算才靠谱?

标准分类 AUC 对 uplift 没意义——它衡量排序能力,但 uplift 关注的是“排在前 10% 的人里,有多少真因干预而转化”。Qini 系数才是主流指标,本质是 uplift 曲线和随机线围成的面积。但多数人直接调 causalml.metrics.qini_score 却忽略输入格式:它要求传入的是原始预测值(非概率差)、真实 y、干预标识 T,且三者顺序必须严格一致(不能 shuffle 后再切片)。

立即学习Python免费学习笔记(深入)”;

  • 确保 y, T, uplift_preds 是同序、等长的 numpy Array,且未被重采样打乱
  • uplift_preds 必须是模型输出的 raw uplift score(比如 Tlearner 输出的差值),不是归一化后的分位数
  • 计算 Qini 前先做 np.argsort(-uplift_preds) 得到排序索引,再按此索引重排 yT,否则曲线会失真
  • 小样本下 Qini 波动大,建议同时画出 Qini curve(横轴为累计覆盖率,纵轴为累计 uplift),比单点分数更可信

真正难的不是跑通代码,是确保 T 是随机分配的——如果数据来自历史运营(非 A/B 测试),所有 uplift 模型的估计都带偏误,这时再调参也没用。

text=ZqhQzanResources