alpha=0.2
bins=30
plt.figure(figsize=(12,8))
plt.hist(cate_t, alpha=alpha, bins=bins, label='T Learner')
plt.hist(cate_x, alpha=alpha, bins=bins, label='X Learner')
plt.hist(cate_x_no_p, alpha=alpha, bins=bins, label='X Learner (no propensity score)')
plt.hist(cate_r, alpha=alpha, bins=bins, label='R Learner')
plt.hist(cate_r_no_p, alpha=alpha, bins=bins, label='R Learner (no propensity score)')
plt.vlines(cate_s[0], 0, plt.axes().get_ylim()[1], label='S Learner',
linestyles='dotted', colors='green', linewidth=2)
plt.title('Distribution of CATE Predictions by Meta Learner')
plt.xlabel('Individual Treatment Effect (ITE/CATE)')
plt.ylabel('# of Samples')
_=plt.legend()
模型输出的分布,几个模型基本分布是一致的
Validating Meta-Learner Accuracy
train_summary, validation_summary = get_synthetic_summary_holdout(simulate_nuisance_and_easy_treatment,
n=10000,
valid_size=0.2,
k=10)
从结果可以对比差异还是蛮大的,还有KL Divergence散度指标,注意,simulate_nuisance_and_easy_treatment
是一个模拟数据的函数,get_synthetic_summary_holdout
模拟之后得到的结论,所以这个函数主要是在模拟运行。
如果有真实数据需要自己计算MSE / KL Divergence了。
按误差再来画一个各模型的对比图:
scatter_plot_summary_holdout(train_summary,
validation_summary,
k=10,
label=['Train', 'Validation'],
drop_learners=[],
drop_cols=[])
bar_plot_summary_holdout(train_summary,
validation_summary,
k=10,
drop_learners=['S Learner (LR)'],
drop_cols=[])
三个指标的柱状图,error of ATE / MSE / KL散度
# Single simulation 生成数据
train_preds, valid_preds = get_synthetic_preds_holdout(simulate_nuisance_and_easy_treatment,
n=50000,
valid_size=0.2)
#distribution plot for signle simulation of Training 查看数据分布
distr_plot_single_sim(train_preds, kind='kde', linewidth=2, bw_method=0.5,
drop_learners=['S Learner (LR)',' S Learner (XGB)'])
其中来重点看一下get_synthetic_preds_holdout
生成之后数据张什么样子,
因为生成过程比较慢,建议把n调小一些,其中train_preds
是,涵盖了,元数据,倾向得分,各类模型的估计结果:
{'Actuals': array([0.79643095, 0.95486817, 0.76997445, ..., 0.75298567, 0.57918784,
0.50598952]),
'generated_data': {'y': array([2.82809532, 0.83627125, 2.96923917, ..., 3.69930311, 2.11858631,
2.08442807]),
'X': array([[0.80662423, 0.78623768, 0.55714673, 0.78484245, 0.7062874 ],
[0.9777165 , 0.93201984, 0.94806163, 0.27111164, 0.91731333],
[0.94459763, 0.59535128, 0.94004736, 0.78097312, 0.68469675],
[0.9168486 , 0.58912275, 0.1413644 , 0.40006979, 0.21380953],
[0.68509846, 0.47327722, 0.476474 , 0.5284623 , 0.7752548 ],
[0.7854881 , 0.22649094, 0.79246468, 0.23035102, 0.46786142]]),
'w': array([1, 0, 0, ..., 1, 1, 1]),
'tau': array([0.79643095, 0.95486817, 0.76997445, ..., 0.75298567, 0.57918784,
0.50598952]),
'b': array([2.0569544 , 1.4065011 , 2.49147132, ..., 1.75627446, 1.76858932,
1.16561357]),
'e': array([0.9 , 0.27521434, 0.9 , ..., 0.9 , 0.85139268,
0.53026066])},
'S Learner (LR)': array([0.67412079, 0.67412079, 0.67412079, ..., 0.67412079, 0.67412079,
0.67412079]),
'S Learner (XGB)': array([0.71599877, 1.01481819, 0.45305347, ..., 1.33423424, 0.76635182,
0.54931992]),
'T Learner (LR)': array([1.02410448, 1.23423655, 0.98041236, ..., 0.96302446, 0.76681856,
0.6616715 ]),
'T Learner (XGB)': array([1.39729691, 2.1762352 , 0.18748665, ..., 1.81221414, 1.25306892,
0.5382663 ]),
'X Learner (LR)': array([1.02410448, 1.23423655, 0.98041236, ..., 0.96302446, 0.76681856,
0.6616715 ]),
'X Learner (XGB)': array([ 0.86962565, 2.17324671, -0.32896739, ..., 1.60033008,
1.33514268, 0.41377797]),
'R Learner (LR)': array([1.12468185, 1.35693603, 1.04248628, ..., 1.00324719, 0.75967883,
0.57261269]),
'R Learner (XGB)': array([0.49208722, 1.1459806 , 0.0804432 , ..., 1.74274731, 1.07263219,
0.48373923])}
# Scatter Plots for a Single Simulation of Training Data
scatter_plot_single_sim(train_preds)
训练集的散点图:
计算AUUC:
# Cumulative Gain AUUC values for a Single Simulation of Training Data
get_synthetic_auuc(train_preds, drop_learners=['S Learner (LR)'])
主要参考的是文档:binary_policy_learner_example.ipynb
另外一个更全面的在:uplift_tree_visualization.ipynb
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
from sklearn.model_selection import cross_val_predict, KFold
from sklearn.ensemble import GradientBoostingRegressor, GradientBoostingClassifier
from sklearn.tree import DecisionTreeClassifier
from causalml.optimize import PolicyLearner
from sklearn.tree import plot_tree
from lightgbm import LGBMRegressor
from causalml.inference.meta import BaseXRegressor
# 生成数据 - 干预是二分类的
np.random.seed(1234)
n = 10000
p = 10
X = np.random.normal(size=(n, p))
ee = 1 / (1 + np.exp(X[:, 2]))
tt = 1 / (1 + np.exp(X[:, 0] + X[:, 1])/2) - 0.5
W = np.random.binomial(1, ee, n)
Y = X[:, 2] + W * tt + np.random.normal(size=n)
policy_learner = PolicyLearner(policy_learner=DecisionTreeClassifier(max_depth=2), calibration=True)
policy_learner.fit(X, W, Y)
plt.figure(figsize=(15,7))
plot_tree(policy_learner.model_pi)
可以得到树的分裂图
同时也可以后续计算ITE,
learner_x = BaseXRegressor(LGBMRegressor())
ite_x = learner_x.fit_predict(X=X, treatment=W, y=Y)
pd.DataFrame({
'DR-DT Optimal': [np.mean((policy_learner.predict(X) + 1) * tt / 2)],
'True Optimal': [np.mean((np.sign(tt) + 1) * tt / 2)],
'X Learner': [
np.mean((np.sign(ite_x) + 1) * tt / 2)
基于神经网络的方法比较新,这里简单举一个例子——DragonNet。该方法主要工作是将propensity score估计和uplift score估计合并到一个网络实现。
首先,引述了可用倾向性得分代替X做ATE估计
然后,为了准确预测ATE而非关注到Y预测上,我们应尽可能使用 X中与 T 相关的部分特征。
其中一种方法就是首先训练一个网络用X预测T,然后移除最后一层并接上Y的预测,则可以实现将X中与T相关的部分提取出来(即倾向性得分
e 相关),并用于Y的预测。
简单参考:【Uplift】建模方法篇
然后这里文档有两个数据集的应用,都在案例:dragonnet_example.ipynb,这里截取一个来简单看一下:
import pandas as pd
import numpy as np
from matplotlib import pyplot as plt
import seaborn as sns
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split, StratifiedKFold
from sklearn.linear_model import LogisticRegressionCV, LogisticRegression
from xgboost import XGBRegressor
from lightgbm import LGBMRegressor
from sklearn.metrics import mean_absolute_error
from sklearn.metrics import mean_squared_error as mse
from scipy.stats import entropy
import warnings
from causalml.inference.meta import LRSRegressor
from causalml.inference.meta import XGBTRegressor, MLPTRegressor
from causalml.inference.meta import BaseXRegressor, BaseRRegressor, BaseSRegressor, BaseTRegressor
from causalml.inference.tf import DragonNet
from causalml.match import NearestNeighborMatch, MatchOptimizer, create_table_one
from causalml.propensity import ElasticNetPropensityModel
from causalml.dataset.regression import *
from causalml.metrics import *
import os, sys
%matplotlib inline
warnings.filterwarnings('ignore')
plt.style.use('fivethirtyeight')
sns.set_palette('Paired')
plt.rcParams['figure.figsize'] = (12,8)
数据载入,元数据在官方github上:
df = pd.read_csv(f'data/ihdp_npci_3.csv', header=None)
cols = ["treatment", "y_factual", "y_cfactual", "mu0", "mu1"] + [f'x{i}' for i in range(1,26)]
df.columns = cols
X = df.loc[:,'x1':]
treatment = df['treatment']
y = df['y_factual']
tau = df.apply(lambda d: d['y_factual'] - d['y_cfactual'] if d['treatment']==1
else d['y_cfactual'] - d['y_factual'],
axis=1)
几个基础模型先跑一下然后对比:
p_model = ElasticNetPropensityModel()
p = p_model.fit_predict(X, treatment)
s_learner = BaseSRegressor(LGBMRegressor())
s_ate = s_learner.estimate_ate(X, treatment, y)[0]
s_ite = s_learner.fit_predict(X, treatment, y)
t_learner = BaseTRegressor(LGBMRegressor())
t_ate = t_learner.estimate_ate(X, treatment, y)[0][0]
t_ite = t_learner.fit_predict(X, treatment, y)
x_learner = BaseXRegressor(LGBMRegressor())
x_ate = x_learner.estimate_ate(X, treatment, y, p)[0][0]
x_ite = x_learner.fit_predict(X, treatment, y, p)
r_learner = BaseRRegressor(LGBMRegressor())
r_ate = r_learner.estimate_ate(X, treatment, y, p)[0][0]
r_ite = r_learner.fit_predict(X, treatment, y, p)
之后是DragonNet模型:
dragon = DragonNet(neurons_per_layer=200, targeted_reg=True)
dragon_ite = dragon.fit_predict(X, treatment, y, return_components=False)
dragon_ate = dragon_ite.mean()
训练的蛮快:
Train on 597 samples, validate on 150 samples
Epoch 1/30
597/597 [==============================] - 2s 3ms/sample - loss: 1239.5969 - regression_loss: 561.7198 - binary_classification_loss: 37.7623 - treatment_accuracy: 0.7590 - track_epsilon: 0.0339 - val_loss: 423.3901 - val_regression_loss: 156.0984 - val_binary_classification_loss: 33.2239 - val_treatment_accuracy: 0.7244 - val_track_epsilon: 0.0325
Epoch 2/30
597/597 [==============================] - 0s 71us/sample - loss: 290.8331 - regression_loss: 118.9768 - binary_classification_loss: 30.6743 - treatment_accuracy: 0.8561 - track_epsilon: 0.0319 - val_loss: 236.9888 - val_regression_loss: 84.3624 - val_binary_classification_loss: 34.7734 - val_treatment_accuracy: 0.7244 - val_track_epsilon: 0.0302
Epoch 3/30
597/597 [==============================] - 0s 69us/sample - loss: 232.0476 - regression_loss: 96.7705 - binary_classification_loss: 27.2036 - treatment_accuracy: 0.8529 - track_epsilon: 0.0301 - val_loss: 220.0190 - val_regression_loss: 71.6871 - val_binary_classification_loss: 37.6016 - val_treatment_accuracy: 0.7244 - val_track_epsilon: 0.0307
Epoch 4/30
最后几个模型一起来看一下:
df_preds = pd.DataFrame([s_ite.ravel(),
t_ite.ravel(),
x_ite.ravel(),
r_ite.ravel(),
dragon_ite.ravel(),
tau.ravel(),
treatment.ravel(),
y.ravel()],
index=['S','T','X','R','dragonnet','tau','w','y']).T
df_cumgain = get_cumgain(df_preds)
df_result = pd.DataFrame([s_ate, t_ate, x_ate, r_ate, dragon_ate, tau.mean()],
index=['S','T','X','R','dragonnet','actual'], columns=['ATE'])
df_result['MAE'] = [mean_absolute_error(t,p) for t,p in zip([s_ite, t_ite, x_ite, r_ite, dragon_ite],
[tau.values.reshape(-1,1)]*5 )
] + [None]
df_result['AUUC'] = auuc_score(df_preds)
plot_gain(df_preds)
从AUUC来看,几个模型各有好坏
主要参考文档:feature_interpretations_example
里面内容比较多,就截取一些
import pandas as pd
import numpy as np
import matplotlib.pyplot as plt
from sklearn.ensemble import RandomForestRegressor, GradientBoostingRegressor
from sklearn.tree import DecisionTreeRegressor
from xgboost import XGBRegressor
from lightgbm import LGBMRegressor
from causalml.inference.meta import BaseSRegressor, BaseTRegressor, BaseXRegressor, BaseRRegressor
from causalml.inference.tree import UpliftTreeClassifier, UpliftRandomForestClassifier
from causalml.dataset.regression import synthetic_data
from sklearn.linear_model import LinearRegression
import shap
import matplotlib.pyplot as plt
import time
from sklearn.inspection import permutation_importance
from sklearn.model_selection import train_test_split
import os
import warnings
warnings.filterwarnings('ignore')
os.environ['KMP_DUPLICATE_LIB_OK'] = 'True' # for lightgbm to work
%reload_ext autoreload
%autoreload 2
%matplotlib inline
plt.style.use('fivethirtyeight')
n_features = 25
n_samples = 10000
y, X, w, tau, b, e = synthetic_data(mode=1, n=n_samples, p=n_features, sigma=0.5)
w_multi = np.array(['treatment_A' if x==1 else 'control' for x in w])
e_multi = {'treatment_A': e}
feature_names = ['stars', 'tiger', 'merciful', 'quixotic', 'fireman', 'dependent',
'shelf', 'touch', 'barbarous', 'clammy', 'playground', 'rain', 'offer',
'cute', 'future', 'damp', 'nonchalant', 'change', 'rigid', 'sweltering',
'eight', 'wrap', 'lethal', 'adhesive', 'lip'] # specify feature names
model_tau = LGBMRegressor(importance_type='gain') # specify model for model_tau
S-Learner为代表来看一下:
base_algo = LGBMRegressor()
# base_algo = XGBRegressor()
# base_algo = RandomForestRegressor()
# base_algo = LinearRegression()
slearner = BaseSRegressor(base_algo, control_name='control')
slearner.estimate_ate(X, w_multi, y)
slearner_tau = slearner.fit_predict(X, w_multi, y)
# 模型的重要性方法一:AUTO
slearner.plot_importance(X=X,
tau=slearner_tau,
normalize=True,
method='auto',
features=feature_names)
# 重要性方法二:permutation方法
slearner.get_importance(X=X,
tau=slearner_tau,
method='permutation',
features=feature_names,
random_state=42)
SHAP值的计算:
shap_slearner = slearner.get_shap_values(X=X, tau=slearner_tau)
shap_slearner
# Plot shap values without specifying shap_dict
slearner.plot_shap_values(X=X, tau=slearner_tau, features=feature_names)
CausalML,这是一个开放源码的Python包,它提供了一套基于最近研究的机器学习算法的提升建模和因果推理方法。我们将介绍CausalML的主要组成部分:(2) 验证/分析方法(如合成数据生成、AUUC、敏感性分析、可解释性),(3) 优化方法(如策略优化、价值优化、单元选择)。github:https://github.com/uber/causalml其余两篇开源项目的文章:因果推断笔记——因果图建模之微软开源的EconML(五)因果推断笔记——因果图建模之微软开源的dowhy(一)
项目地址:https://gitcode.com/uber/causalml
CausalML是Uber公司开源的一个机器学习库,它专注于因果推断和预测模型的构建。这个项目结合了统计学、经济学和机器学习领域的最佳实践,为数据科学家提供了一套强大的工具,帮助他们在复杂的业务场景中进行因果效应评估。
CausalML基于Pyth...
这个项目很稳定,可以长期支持。 它可能包含新的实验代码,其API可能会更改。
因果ML:用于ML进行抬升建模和因果推理的Python包
Causal ML是一个Python软件包,它提供了一套基于最近研究的,使用机器学习算法的提升模型和因果推理方法。 它提供了一个标准界面,允许用户从实验或观察数据中估计条件平均治疗效果(CATE)或个体治疗效果(ITE)。 本质上,它为具有观察特征X用户估计了干预T对结果Y的因果影响,而无需对模型形式做出强烈假设。 典型的用例包括
广告系列定位优化:提高广告系列投资回报率的重要手段是将广告定位到在给定的KPI(例如参与度或销售)方面有良好响应的一组客
https://arxiv.org/pdf/2002.11631.pdf
摘要:在本文中,来自 Uber 的研究者推出了针对因果推理和机器学习算法的 Python 实现。近年来,结合因果推理和机器学习的算法早已成为热门话题。CasualML 包通过该领域一系列方法的 Python 实现,力图缩小方法论理论研究与实际应用之间的差距。
本文着重介绍了 CasualML 包的核心概念、应用范围和应用实例。此外,研究者计划将来添加更多 SOTA 增益模型,并探索更多融合机器学习与因果推理的建模方法以
项目名称:Causal ML: A Python Package for Uplift Modeling and Causal Inference with ML
项目名称:Causal ML:使用机器学习进行提升建模和因果推理的Python包
CausalML是uber的开源项目,用于使用机器学习方法进行提升建模和因果推理方法。它允许用户从实验或观察数据估计条件平均治疗效果(CATE)或个体...
机器学习车间存储库中的
因果建模
这是上机器学习研讨会中
因果建模的研讨会资料库。
Altdeep.ai讲习班是通过在线讲授与讲习班教官进行的一对一会议相结合进行授课的。 访问Altdeep.ai以获取有关研讨会内容和费用的信息。 此回购中的材料是
开源的且免费的。
大纲和时间表
NEU学生:如果您想报名参加此课程并且有疑问,请通过与我,而不是通过我的NEU电子邮件与我联系。
完成本课程后,您将能够在顶级技术组织的数据科学和机器学习团队的决策系统中构建
因果推理算法。 您将实施一个证明该能力的投资组合项目。 您将使用基于PyTorch的概率深度学习
框架来实施家庭作业和班级项目,并且在课程结束时将成为使用此
框架的专家。
这门课程适合谁?
如果您满足以下条件,您将从本课程中获得最大收益:
您熟悉随机变量,联合概率分布,条件概率分布,贝叶斯规则和贝叶斯统计中的基本思想以及期望。
上午4:00 - 7:00 AM 2021年8月15日
2021 年 8 月 14 日下午 4:00 - 晚上 7:00
时间 2021 年 8 月 14 日下午 1:00 - 4:00
实时缩放链接
在会议期间在 KDD 21 虚拟平台内共享。
近年来,无论是学术研究还是行业应用,都越来越多地使用机器学习方法来衡量细粒度的
因果效应,并根据这些
因果估计设计最佳策略。 和等
开源软件包为应用研究人员和行业从业者提供了一个统一的接口,使用各种机器学习方法进行
因果推理。 本教程将涵盖的主题包括元学习器的条件处理效果估计器和基于树的算法、模型验证和敏感性分析、优化算法(包括策略精简和成本优化)。 此外,本教程将演示这些算法在行业用例中的生成。
EconML:用于基于ML的异构处理效果估计的Python包
EconML是一个Python软件包,用于通过机器学习从观察数据中估计异构处理效果。 此软件包是作为Microsoft Research的一部分设计和构建的,目的是将最新的机器学习技术与计量经济学相结合,以使自动化解决复杂的因果推理问题。 EconML的承诺:
在计量经济学和机器学习的交集中实现文献中的最新技术
保持建模效果异质性的灵活性(通过诸如随机森林,增强,套索和神经网络之类的技术),同时保留对所学模型的因果解释,并经常提供有效的置信区间
使用统一的API
建立在用于机器学习和数据分析的标准Python软件包的基础上
机器学习的最大希望之一就是在众多领域中自动化决策。 许多数据驱动的个性化决策方案的核心是对异构处理效果的估计:对于具有特定特征集的样本,干预对感兴趣结果的因果关系是什么? 简而言之,该工具包旨在测量某些治疗变量T对结果变量Y的因果效应,控制一组特征X, W以及该效应如何随X 。 所实施的方法甚至适用于观测(非实验或历史)数据集。 为了使估计结果具有因果关系,有些方法假定没有观察到的混杂因素(即, X,
参考:https://github.com/uber/causalml
依赖:https://github.com/uber/causalml/blob/master/requirements.txt
安装:sudo pip install causalml
报错:ImportError: cannot import name ‘factorial’
问题解决:sudo pip install statsmodels --upgrade
index-url = http://mirrors.aliyun.com/pypi/simple/
[install]
trusted-host = mirrors.aliyun.com
pip install -r requirements.txt
pip install causalml --default-timeou...
微软EconML简介:基于机器学习的Heterogeneous Treatment Effects估计
机器学习最大的promise之一是在许多领域实现决策的自动化。
许多数据驱动的决策场景的核心问题是对heterogeneous treatment effects的估计,也即:对于具有特定特征集的样本,干预对输出结果的causal effect是什么?
简言之,这个Python工具包旨在:
测量某些干预变量T对结果变量Y的causal effect
控制一组特征X和W,来衡量causal effect如
Uber Golang规范是Uber专门为其Golang代码库制定的一套代码编写指南和规范。以下是Uber Golang规范的主要特点:
命名规范:采用驼峰命名法,遵循Go语言的命名约定。使用有意义且描述性强的名称,避免使用缩写。
包和依赖管理:使用Go的标准工具go mod来管理包和依赖。在代码库的根目录下创建go.mod文件,明确定义需要使用的外部依赖。
代码布局:代码文件应按照功能逻辑进行组织,每个文件夹下应包含一个独立的Go模块。避免使用过深的嵌套文件夹结构。
错误处理:在函数签名中使用`error`类型,以便清晰地表示可能出现的错误。避免使用panic来处理错误,而是使用返回错误信息来处理。
并发:使用Go语言提供的并发原语,如goroutine和channel,来编写并发代码。避免使用传统的同步原语,如互斥锁。
测试:为每个包编写相应的测试代码,测试代码应放在与源代码相同的包中,以便方便进行单元测试。使用`go test`来运行测试。
文档:代码应有清晰的注释,包括每个公共函数和方法的文档注释。注释应使用规范的格式,方便生成文档。
性能优化:在编写代码时要考虑性能,并进行必要的性能优化。可以使用Go的性能分析工具来找出性能瓶颈并进行优化。
此外,Uber Golang规范还提供了关于代码风格、错误处理、日志记录、版本管理和代码重用等方面的指导。遵循这些规范可以使代码更易于理解、维护和扩展,并提高代码库的整体质量。