了解因果关系的概念、算法和代码:利用CausalML工具
简而言之:近年来,结合因果推理和机器学习的算法一直是热门话题。在这篇文章中,我将介绍一种强大的客户定位技术——提升建模。我们将探讨其目标、基本概念以及关键算法,并通过一个使用CausalML的案例研究来举例说明。
照片由 Artem Beliaikin 拍摄,来自 Unsplash。
如果你更愿意直接查看示例代码的话,可以访问我的GitHub仓库。如果能给我点个 star,我会不胜感激!
GitHub - takechanman1228/Effective-Uplift-Modeling 通过在 GitHub 上注册账号参与此项目开发。 1. 我们应该提高销售额,应该针对谁?提升模型法有助于识别那些在被特定营销活动(如推广)所影响后更有可能进行购买的客户,相比之下,当他们未受到此类营销活动影响时。这种方法在成本高昂的营销活动中尤为宝贵,因为在这些活动中,高效分配资源至关重要。
现在,我们来仔细看看我们要瞄准的客户。
2. 理解目标顾客来更好地服务他们。为了有效地应用客户提升模型,我们可以将客户划分为四种不同的类型,比如:
- 可能被说服的顾客:只有在得到特别对待的情况下才会购买产品的顾客。这些是目标提升模型的主要目标。
- 确定买家:无论是否得到特别对待,都会购买产品的顾客。
- 无望顾客:即使得到特别对待也不会购买产品的顾客。
- 反效果顾客:这些是极为罕见的顾客,即使收到特别对待,反而更不可能购买。
关键点在于,营销资源,如优惠券,不应浪费在稳赚、无望的客户或沉睡的潜在客户上,因为这类群体很难带来正向的投资回报。
构建提升模型主要有两种方法。
- 元学习方法:我在之前的一篇文章中介绍过这种方法,它通过将客户按估计的处理效应从高到低排序,来优先接触那些估计效果最好的客户。
- 基于树的方法:这种方法使用专门用于提升建模的提升决策树和提升随机森林。这种方法的一大好处是它可以同时处理多个不同的处理组。例如,我们不仅能够测试单一折扣,还可以比较不同折扣的效果——比如5%,10%,和20%,以找到对每个客户群体最有效的折扣。这种灵活性使得基于树的方法非常适合在实际业务中使用。
要理解提升树的概念,我们可以将其与传统的决策树进行比较。传统的决策树主要用于预测结果,例如是否会购买产品。相比之下,提升树回答的是因果关系问题,如“我们应该给谁发优惠券?”
提升树模型区分了享受优惠和未享受优惠的客户,使我们能够识别出提供优惠券所产生的潜在提升。现在我们来仔细看看每种方法的细节。
我们从传统的决策树开始。根据选择的决策节点,构建决策树有多种方法。
但是,我们该如何选择最合适的决策节点来构建更好的决策树呢?
考虑下面的图形中的两个树状图:左边的树按照“年龄”进行分割,而右边的树则按照“位置”进行分割。黑色图标表示购买过的客户,而白色图标表示未购买的客户。
哪一棵树更适合进行更好的划分?
正确答案是右边的树。左边的树中,购买者和非购买者在两个集群中混在一起。相比之下,在右边的树中,购买者和非购买者被清楚地分隔开了。
但我们又该如何衡量这种判断呢?
对于分割标准,可以使用“Gini不纯”。
这种指标称为“基尼不纯度”(Gini指数),它帮助我们量化决策树中各节点的纯度。基尼不纯度通过以下公式定义:
Gini指数 = 1 — (p₁² + p₀²)
其中 p1 是购买的概率,而 p0 则是不购买的概率。
例如,在如下的第一个决策树中,基尼不纯度被计算为0.44。
相比之下,第二个决策树的基尼不纯度为0,这表明其树结构更有效。这种差异表明,用“位置”作为决策节点可以得到更好的分类结果,它能更有效地分隔购买者和非购买者。
现在,我们来探索一下提升树吧。提升树的主要目的是确定“我们应该给哪些人发放优惠券?”换句话说,目标是最大化这两组顾客之间购买率的差异。为了达到这个目标,我们会分别分析那些收到优惠券的顾客和没有收到优惠券的顾客。
请看下面的两个提升树。正如之前所提到的,右边的树提供了更佳的分割,因为它更有效地将买家与不买家区分开。
但是我们如何量化这种差异呢?为此,我们转向信息理论中的度量方法(如熵等)。
对于划分标准,可以使用分歧度量。
为了衡量分割的质量,我们可以使用以下指标,例如Kullback-Leibler (KL) 距离或欧几里得距离。这里,我们将采用平方欧几里得距离。它可以通过以下公式计算:
欧式平方距离 = (P(0) — Q(0))² + (P(1) — Q(1))²
(即两点之间距离的平方)
例如,在这个公式里:
- P(1) 和 P(0) 分别表示实验组的购买概率和未购买概率。
- Q(1) 和 Q(0) 则分别表示对照组的购买概率和未购买概率。
根据这个指标,下面的第一个提升树模型的差异为1。
另一方面,第二个决策树的基尼指数为0。这表明第二棵树实现了更高的基尼指数,这说明它更有效地提高了提升效果。
存在两个流行的因果机器学习的库。特别是再提升模型方面,我建议使用 CausalML ,它提供了一系列适用于各种应用场景的实用函数。
您能在这里访问完整代码:
如需翻译代码,请提供代码段。
[Effective-Uplift-Modeling/simple_end_to_end_uplift_modeling_causalml.ipynb 在 main ·…点击链接: 加入 takechanman1228/Effective-Uplift-Modeling 项目开发,通过在 GitHub 上创建一个帐户。 数据集合这个示例代码演示了如何使用来自广告行业的知名数据集Criteo(一个)来使用提升模型。该案例研究的目标是优先对数字广告定位的客户进行定位。
该数据集包含用户数据,包含11个特性、一个处理标志和一个转化标志,分别表示用户是否见过广告以及他们是否在之后做出了购买。
安装库包要起步,请安装如下两个库:CausalML
用于因果推断模型和 scikit-uplift
用于下载 Criteo 数据集。
pip install causalml scikit-uplift
接下来,我们导入需要用到的库。
# 导入所需的库
import numpy as np
import pandas as pd
from causalml.inference.tree import UpliftRandomForestClassifier
from causalml.metrics import plot_gain, plot_qini
from sklearn.model_selection import train_test_split
import seaborn as sns
import matplotlib.pyplot as plt
import importlib
from IPython.display import display
# 确保已经安装了所需的库
print(importlib.metadata.version('causalml'))
原始数据包含了11个用户特征,还有一个治疗标识和一个转化标识。
从sklift.datasets模块导入fetch_criteo
X, y, treatment = fetch_criteo(target_col='conversion', treatment_col='treatment', return_X_y_t=True)
df = X.copy()
df['conversion'] = y.astype('int64')
df['treatment'] = treatment.astype('object').replace({0: 'control', 1: 'treatment'})
# 注释:# df['user_id'] = df.index
df.head()
让我们来看看数据概要
该数据集包含超过1300万行数据,且存在不平衡问题:大约85%的用户被广告曝光(实验组),而15%的用户没有被曝光(控制组)。
print('总共有多少样本:{}'.format(len(df)))
总样本数量:13,979,592
以下代码计算'treatment'列中每个值出现的比例:
df['treatment'].value_counts(normalize=True)
治疗组占比 0.85 对照组占比 0.15
df['conversion'].value_counts(normalize = True)
0 0.997083
1 0.002917
这些数值表示某种概率或技术输出。
训练提升模型的过程在将数据分为training set和testing set之后,我们使用提升随机森林来训练模型。CausalML
库的接口和scikit-learn
等其他机器学习库的接口类似。
# 将数据分为训练集和测试集
X_train, X_test, y_train, y_test, treatment_train, treatment_test = train_test_split(
df.drop(columns=['conversion', 'treatment']), df['conversion'], df['treatment'],
test_size=0.3, random_state=42)
# 拟合提升随机森林模型
uplift_rf = UpliftRandomForestClassifier(control_name='control')
uplift_rf.fit(X_train.values, treatment=treatment_train.values, y=y_train.values)
# 使用训练好的模型预测提升效果
y_pred = uplift_rf.predict(X_test)
可视化技术
CausalML
提供了工具来帮助你可视化提升树的结构。
# 绘制 uplift 树
from IPython.display import Image
graph = uplift_tree_plot(uplift_tree.fitted_uplift_tree, X_train.columns)
Image(graph.create_png())
我们还可以分析特征的重要程度,看看哪些变量对模型的预测结果影响较大。
# 可视化提升树特征的重要性
pd.Series(uplift_tree.feature_importances_, index = X_train.columns).sort_values().plot(kind='barh', figsize=(12,8))
评估准备阶段
为了准备评估,我们为每个用户创建了一个包含is_treated
、conversion
和 uplift
列的 DataFrame。正的 uplift 表示广告是有益的,而负的 uplift 表示最好不要展示该广告,因为它可能对用户不利。
# 将预测结果转换为 DataFrame
uplift_results = pd.DataFrame(y_pred, columns=uplift_rf.classes_[1:])
# 计算最佳治疗方案
best_treatment = np.where(uplift_results['treatment'] < 0, 'control', 'treatment') # 如果治疗效果小于0,则认定为对照组,否则为治疗组
# 计算AUC指标
auuc_metrics = (uplift_results.assign(is_treated=(treatment_test.values != 'control').astype(int), # 计算是否为治疗组
conversion=pd.concat([X_test, y_test, treatment_test], axis=1)['conversion'].values, # 计算转化率
uplift=uplift_results.max(axis=1)) # 计算提升值
.drop(columns=list(uplift_rf.classes_[1:])))
提升曲线:总收益
提升曲线(Uplift Curve)展示了累计提升收益,表明该模型如何有效地定位那些可能在看到广告后进行转化的用户。提升模型曲线与随机目标线之间的区域被称为AUUC(提升曲线下的面积)。
# 绘制提升曲线
plot_gain(auuc_metrics, outcome_col='conversion', treatment_col='is_treated')
AUUC评分用来衡量提升模型的表现,类似于AUC(ROC曲线下的面积)。接近1的评分意味着表现非常好,而接近0.5的评分则表示表现和随机猜测差不多。在这种情况下,AUUC评分为0.84,表明表现相当不错。
from causalml.metrics import auuc_score
# 计算AUUC得分
score = auuc_score(auuc_metrics, outcome_col='conversion', treatment_col='is_treated')
# 输出得分结果
print(score)
提取特定用户群体提升 0.844375
随机数 0.506221
最后,我们根据每个客户的提升分数值计算出其所在的十分位,从而选出目标客户。这让我们可以根据预算优先联系哪些客户。
# 按 'uplift' 从高到低对 uplift_results 数据框进行排序
uplift_results['user_id'] = X_test.index
uplift_results.rename(columns={'treatment': 'uplift'}, inplace=True)
uplift_results_sorted = uplift_results.sort_values(by='uplift', ascending=False).reset_index(drop=True)
# 以下是按提升值排序的客户列表:
print("打印客户列表,如下:")
display(uplift_results_sorted[['user_id', 'uplift']].head(10)) # 展示前10名客户的用户ID和提升值
通过将客户排名并划分成十个等级,您可以确定您的活动最有效的目标群体,并据此优化您的营销预算。
# 计算排名和分位数标签
uplift_results_sorted['rank'] = uplift_results_sorted['uplift'].rank(method='first', ascending=False)
uplift_results_sorted['decile'] = pd.qcut(uplift_results_sorted['rank'], 10, labels=False)
decile_labels = [
"前10%", "前10%-20%", "前20%-30%", "前30%-40%", "前40%-50%",
"前50%-60%", "前60%-70%", "前70%-80%", "前80%-90%", "最后10%"
]
# 定义列的顺序
column_order = ['user_id', 'uplift', 'rank', 'decile', 'decile_label']
uplift_results_sorted['decile_label'] = uplift_results_sorted['decile'].map(lambda x: decile_labels[x])
display(uplift_results_sorted[column_order].head(10))
uplift_results_sorted[column_order].to_csv('customer_list_sorted_by_uplift.csv', index=False)
print("客户列表已保存到文件'customer_list_sorted_by_uplift.csv'")
5 结论
这里有几个重要的点。
- 提升建模 帮助识别更可能对定向治疗作出积极回应的客户,优化营销策略并提高投资回报。
- 基于树的方法(如决策树) 是专门为提升建模设计的,使用偏差度量。
- CausalML 是一个专为提升建模设计的强大库,提供实施、可视化和性能评估的工具。
- CausalML : https://github.com/uber/causalml
- Criteo 数据 : https://ailab.criteo.com/criteo-uplift-prediction-dataset
- Wayfair 技术文章 : https://www.aboutwayfair.com/tech-innovation/modeling-uplift-directly-uplift-decision-tree-with-kl-divergence-and-euclidean-distance-as-splitting-criteria
- Python 中的因果推断 : https://www.amazon.com/Causal-Inference-Discovery-Python-learning/dp/1804612987
- 演示代码 : https://github.com/takechanman1228/Effective-Uplift-Modeling/blob/main/simple_end_to_end_uplift_modeling_causalml.ipynb
- YouTube (CodeEmporium) : https://www.youtube.com/watch?v=MFnOYNU5sbk
- YouTube (Pydata 伦敦 2024) : https://www.youtube.com/watch?v=GH7xOPCIfIQ
感谢您的阅读!如果您有任何问题或建议,欢迎在领英上联系我!另外,如果您能在Medium上关注我,我也非常感激。
共同学习,写下你的评论
评论加载中...
作者其他优质文章