# 教程:使用 DoWhy+EconML进行因果推理
关注他
16 人赞同了该文章
本教程介绍如何使用DoWhy+EconML库进行因果推理。在这个过程中,这个教程将强调因果推理与机器学习的联系,也即:如何通过机器学习来建立因果效应的estimators,以及如何使用因果推理来建立更robust的机器学习模型。在数据科学中与因果推理相关的例子:
- A/B实验:如果改变算法,会导致更到的成功率吗?
- 政策决策:如果采用这种治疗/政策,是否会带来更健康的患者/更多的收入?
- 政策评估:现在的政策是有帮助还是有害?
- 归因:人们购买是因为推荐算法吗?还是其它的原因?
在本教程中,可以学到如下内容:
- 了解因果推理对决策的必要性,以及预测(prediction)和决策(decision-making)任务之间的区别;
- 通过因果推理的四个步骤来对因果效应进行评估:模型(model)、识别(identify)、估计(estimate)和反驳(refute);
- 通过DoWhy+EconML仅使用4行代码就可以估计因果效应,并且使用最新的统计和机器学习方法来估计因果效应,并评估其建模假设的鲁棒性;
- 通过Jupyter对真实案例进行研究,在不同的场景中应用因果推理,包括:估计客户忠诚度对未来交易的影响,预测哪些用户将受到干预(例如广告)的积极影响,对产品进行定价,以及估计哪些因子对outcome贡献最大;
- 了解因果推理与现代机器学习面临的挑战之间的关系;
Why causal inference?
许多关键的数据科学任务都与决策( decision-making)有关。数据科学家经常被要求支持各级决策者(decision-makers),期望充分利用数据来支持实现预期的结果。决策者包括:决定投资和资源配置的执行官、决定折扣政策的营销人员、确定要提供哪些功能的产品团队或决定对患者实施哪种治疗的医生。
每个决策者都在问一个假设(what-if)问题。要基于数据给出这些问题的答案,需要了解事件的causes以及如何采取行动来改善未来的结果。
Defining a causal effect
假设我们想知道采取行动A对结果Y的causal effect。要定义因果效果,需要考虑两个世界:世界1(真实世界):采取行动A并观察Y的地方。世界2(反事实世界):没有采取行动A(但其他一切都一样)。因果效应是在现实世界中获得的Y值与反现实世界中获得的Y值之间的差异。
真实世界与反事实世界
换言之,保持其他一切不变的情况下,因为A变化导致的Y的变化。在保持其他事物不变的同时改变A被称为干预,用一个特殊的符号表示: ( )。从形式上讲,因果效应是指Y因A的变化而变化的幅度:
为了进行估计,黄金标准是进行一个随机实验,其中一个随机集合被作用 =1,而另一个子集没有作用也即 =0。这些子集近似于不相交的真实世界和反现实世界,随机化确保了这两个子集之间没有系统性的差异(也即“保持其他一切不变”)。
然而,并不是在所有场景都可以进行随机实验,我们通常需要依靠已经观测或记录的数据来回答因果的问题。这些观察到的数据由于相关性和未观察到的混杂(confounding)而有偏差,因此在A=1和A=0的两个集合中可能存在系统性差异。例如,新的营销活动可能在假期期间展开,新功能可能只应用于高活动用户,或者老年患者可能更容易接受新药,等等。因果推理方法的目的是从数据中消除这种相关性和混杂,并估计一个*干预*的真实效果。
The difference between prediction and causal inference
Two fundamental challenges for causal inference
- 观察不到反事实的世界
- 不能直接计算因果关系
- 必须估计反事实
- 验证存在挑战
- 多个因果机制可以适用于单个数据分布
- 仅数据不足以进行因果推理
- 需要领域知识和假设
The four steps of causal inference
由于没有可用的具有ground-truth的数据与估计值进行比较,因果推理需要一系列步骤来保证一个好的估计值。我们通过一个示例数据集来说明这四个步骤。本教程需要下载两个库:DoWhy和EconML。两者都可以通过以下命令安装:
pip install dowhy econml
step0. 加载数据
# Required libraries
import dowhy
from dowhy import CausalModel
import dowhy.datasets
# Avoiding unnecessary log messges and warnings
import logging
logging.getLogger("dowhy").setLevel(logging.WARNING)
import warnings
from sklearn.exceptions import DataConversionWarning
warnings.filterwarnings(action='ignore', category=DataConversionWarning)
# Load some sample data
data = dowhy.datasets.linear_dataset(
beta=10,
num_common_causes=5,
num_instruments=2,
num_samples=10000,
treatment_is_binary=True)
step1. Modeling
第一步是将我们的领域知识编码成一个因果模型,通常用graph来表示。因果推理分析的结果很大程度上依赖输入假设,因此这一步非常重要。为了估计因果效应,大部分常见的问题涉及指定两类变量:
- 混杂变量(Confounders):这些是干预和outcome的共同的cause。因此,任何观察到的干预和outcome之间的相关性可能只是由于混杂变量,而不是由于干预和outcome之间的因果关系;
- 工具变量(Instrumental Variables):这些是导致干预的特殊变量,但并不直接影响outcome。此外,它们不受任何影响outcome的变量的影响。如果使用正确的方式,工具变量可以帮助减少偏差。
# I. Create a causal model from the data and domain knowledge.
model = CausalModel(
data=data["df"],
treatment=data["treatment_name"],
outcome=data["outcome_name"],
common_causes=data["common_causes_names"],
intrumental_variables=data["instrument_names"])
# visualize the graph
model.view_model(layout="dot")
from IPython.display import Image, display
display(Image(filename="causal_model.png"))
通常,可以指定一个因果图,该图描述给定数据集的数据生成过程。图中的每个箭头都表示因果关系:“A->B”表示变量A导致变量B。
# I. Create a causal model from the data and given graph.
model = CausalModel(
data=data["df"],
treatment=data["treatment_name"][0],
outcome=data["outcome_name"][0],
graph=data["gml_graph"])
model.view_model(layout="dot")
step2. Identification
提供领域知识的两种方式(通过混淆因子和工具变量的命名变量集,或通过因果图)都对应于一个潜在的因果图。给定一个因果图和一个目标量(如A对B的影响),identification的过程是检查给定观测变量是否可以估计目标量。重要的是,identification只考虑观测数据中可用的变量;它不需要数据本身。与上述两类变量相关,因果推理的identification方法主要有两种:
- 后门标准(更一般地说,调整集):如果干预A和结果Y的所有共同原因都可以观测到,那么后门标准意味着可以通过对所有共同原因给定的情况下来识别因果效应。这是一个简化的定义(关于正式定义,请参阅CausalML一书的第3章), 其中 代表A和Y的confounders。
- Instrumental variable (IV) identification:如果有一个工具变量可用,那么即使有共同的原因是不可观察的,那么我们可以估计影响。 IV identification的原理是工具变量只直接影响干预变量,因此工具变量对outcome的影响可以分为两个连续的部分:工具变量对干预的影响和干预对outcome的影响。然后估计工具变量对干预变量的影响效应,以及干预变量对outcome的影响效应。对于只有两个取值的工具变量,估计的效应如下:
# II. Identify causal effect and return target estimands
identified_estimand = model.identify_effect(proceed_when_unidentifiable=True)
print(identified_estimand)
step3. Estimation
顾名思义,在估计步骤来构建一个estimator,该estimator可以计算在上一步中确定的estimand identified。许多估计estimators已经被提出用于因果推理。DoWhy实现了一些标准的estimators,而EconML实现了一组使用机器学习方法的估计器。
我们展示了一个使用DoWhy的倾向评分分层(Propensity Score Stratification)的例子,以及使用EconML实现的基于机器学习的方法Double-ML。
# III. Estimate the target estimand using a statistical method.
propensity_strat_estimate = model.estimate_effect(identified_estimand,
method_name="backdoor.dowhy.propensity_score_stratification")
print(propensity_strat_estimate)
import econml
from sklearn.preprocessing import PolynomialFeatures
from sklearn.linear_model import LassoCV
from sklearn.ensemble import GradientBoostingRegressor
dml_estimate = model.estimate_effect(identified_estimand,
method_name="backdoor.econml.dml.DML",
method_params={
'init_params': {'model_y':GradientBoostingRegressor(),
'model_t': GradientBoostingRegressor(),
'model_final':LassoCV(fit_intercept=False), },
'fit_params': {}
})
print(dml_estimate)
step4. Refutation
最后,检查估计的鲁棒性是因果分析中最重要的一步。我们使用步骤1-3获得了一个估计值,但每个步骤可能都做出了某些假设,但这些假设可能是错的。如果没有一个合适的验证集,这一步可以依赖反驳测试(refutation tests),该测试使用一个estimator的属性来反驳所获得的估计的正确性。例如,反驳测试(placebo_treatment_refuter)检查当干预变量被随机变量替换时,estimator返回估计值0是否与所有其他变量独立。
# IV. Refute the obtained estimate using multiple robustness checks.
refute_results = model.refute_estimate(identified_estimand, propensity_strat_estimate,
method_name="placebo_treatment_refuter")
print(refute_results)
## The Do