目录
理解数据
识别处理变量
识别潜在混杂因素
UCI 银行营销数据集来源于一家真实银行的直接营销活动。这是一个广为人知的数据集,最常被当作分类任务处理,目的是预测客户是否会开设定期存款账户。在这个笔记中,我们展示这个数据集同样适用于因果推断。银行希望增加开设定期存款账户的客户比例,而数据集中包含了一些可以被视为干预措施或治疗方法(我们将这两个术语互换使用)的变量。
理解数据
import numpy as np
import pandas as pddef read_data_from_UCI():"""Reads the bank-marketing data table from a zip file directly from UCI"""import zipfileimport iofrom urllib import requesturl = "https://archive.ics.uci.edu/ml/machine-learning-databases/00222/bank-additional.zip"with request.urlopen(url) as r:with zipfile.ZipFile(io.BytesIO(r.read())) as zf:csv_file = zf.open("bank-additional/bank-additional-full.csv")df = pd.read_csv(csv_file, sep=";")return df
data = read_data_from_UCI()
data.shape
(41188, 21)
data.columnsIndex(['age', 'job', 'marital', 'education', 'default', 'housing', 'loan','contact', 'month', 'day_of_week', 'duration', 'campaign', 'pdays','previous', 'poutcome', 'emp.var.rate', 'cons.price.idx','cons.conf.idx', 'euribor3m', 'nr.employed', 'y'],dtype='object')
根据数据描述:
- 前七个变量('age'-'loan')与客户有关,包括基本的信用特征('default', 'housing', 'loan')。
- 接下来的四个变量与本次营销活动中最后一次与客户的联系有关:联系方式('contact',手机/电话)、日期('month', 'day_of_week')以及联系的持续时间('duration')。'campaign' 表示本次活动中进行的联系次数。
- 随后的三个变量与之前的营销活动有关(如果适用):自上次活动以来的天数('pdays')、之前活动中的联系次数('previous')以及其结果('poutcome')。
- 变量 'emp.var.rate'-'nr.employed' 是经济指标,如就业率和消费者价格指数。
- 最后一个变量 'y' 是客户是否开设定期存款的结果。
我们继续将 'y' 二值化,将 'yes' 映射为值 1。
print(data['y'].unique())from sklearn.preprocessing import LabelEncoder
le = LabelEncoder()
y = pd.Series(le.fit_transform(data['y']))
y.mean()
['no' 'yes']
0.11265417111780131
只有 11.3% 的客户会签约定期存款。
识别处理变量
接下来,我们考虑上述变量中哪些可以被视为银行员工采取的干预措施,以提高积极结果的比例。这些变量立即受限于与当前营销活动相关的变量,因为客户特征和经济状况无法由银行控制,过去发生的事件也无法改变。此外,如这里所述,'duration' 在最后一次联系完成之前是未知的,并且主要由客户决定。对于剩余的变量,在这个笔记中,我们将调查 'contact'(联系方式)和 'campaign'(联系次数)的影响。'day_of_week' 可以像 'contact' 一样处理,如下所示。
我们首先考虑 'contact',并将其编码为一个 0/1 值变量 a(0 表示手机,1 表示电话):
print(data['contact'].unique())
a = pd.Series(le.fit_transform(data['contact']))
a.mean()
['telephone' 'cellular']
0.3652520151500437
识别潜在混杂因素
为了从观察数据中估计因果效应,我们还必须识别哪些变量是潜在的混杂因素,即可能同时影响结果 'y' 以及干预决策的变量。我们需要“调整”(即控制)这些混杂因素,以便隔离干预对 'y' 的因果效应。对于这个数据集,混杂因素的选择可以通过以下方式进行:
1. 遵循避免使用干预后变量的原则,即那些可能受到干预影响的变量;
2. 将自己置于做出决策的假设银行员工的位置。
考虑第一点排除了 'duration',因为它是在最后一次与客户接触后的结果。另一方面,我们将始终将以下变量作为潜在的混杂因素包括进来:
- - 客户特征 'age'-'loan':这些显然会影响客户投资定期存款(结果)的决定。我们假设银行也可能在其记录中有大部分这些信息,并且银行员工在联系客户时可能会参考这些信息。
- - 之前的营销活动 'pdays', 'previous', 'poutcome':这些指标反映了客户之前对银行产品的接受程度,也会成为客户记录的一部分。
- - 经济指标 'emp.var.rate'-'nr.employed':这些条件可能会影响客户的决定以及银行的做法。
confounders = ['age', 'job', 'marital', 'education', 'default', 'housing', 'loan', 'pdays','previous', 'poutcome', 'emp.var.rate', 'cons.price.idx', 'cons.conf.idx', 'euribor3m', 'nr.employed']
对于 'contact' 干预,决策是银行员工应该在下次(也是最后一次)与客户的联系中拨打手机还是座机。因此,我们还将包括 'month' 作为潜在的混杂因素,以考虑任何季节性效应,以及 'campaign',即到目前为止的联系次数。
confounders += ['month', 'campaign']
X = data[confounders]
X.dtypes
age int64
job object
marital object
education object
default object
housing object
loan object
pdays int64
previous int64
poutcome object
emp.var.rate float64
cons.price.idx float64
cons.conf.idx float64
euribor3m float64
nr.employed float64
month object
campaign int64
dtype: object
X = pd.get_dummies(X, prefix_sep='=', drop_first=True)
X.head()