主要讲微软发布的DoWhy 的简单用法
因果推断框架 DoWhy 入门 - 知乎 (zhihu.com)
这个教程很不错
「因果推断」(causal inference)是基于观察数据进行反事实估计,分析干预与结果之间的因果关系的一门科学。虽然在因果推断领域已经有许多的框架与方法,但大部分方法缺乏稳定的实现。DoWhy 是微软发布的一个用于进行端到端因果推断的 Python 库.
DoWhy | An end-to-end library for causal inference — DoWhy | An end-to-end library for causal inference documentation (microsoft.github.io)
本教程介绍了使用 DoWhy+EconML 库进行因果推理的演练。在此过程中,我们将重点介绍与机器学习的联系——机器学习如何帮助构建因果效应估计器,以及因果推理如何帮助构建更强大的机器学习模型
基本上属于因果推理问题的数据科学问题的例子:
- a/b 实验: 如果我改变算法,是否会导致更高的成功率?
- 政策决定: 如果我们采用这种治疗/政策,是否会带来更健康的病人/更多的收入/等等?
- 政策评估: 根据我现在的了解,我的政策有帮助还是有害? 信用归属: 人们购买是因为推荐算法吗?他们还会买吗?
在本教程中,你将: 了解因果推理对于决策的必要性,以及预测和决策任务之间的区别。
使用因果推理的四个步骤: 模型、识别、估计和驳斥,估计因果效应。model, identify, estimate and refute.
看看 DoWhy + EconML 如何帮助你用4行代码来估计因果效应,使用统计学和机器学习的最新方法来估计因果效应,并评估其对建模假设的稳健性。
为什么是因果推断?
许多关键的数据科学任务都与决策有关。经常呼吁数据科学家支持各级决策者,帮助他们最好地利用数据,支持实现预期成果。例如,一个决策投资和资源决策的执行者,一个决定折扣政策的营销人员,一个产品团队优先发布哪些特性,或者一个医生决定给病人治疗。
这些决策者都在问一个假设的问题。数据驱动的对这些问题的回答需要了解事件的原因以及如何采取行动改善未来的结果。
定义因果效应
假设我们想要找到采取行动 a 对结果 y 的因果效应,为了定义因果效应,考虑两个世界:
1.世界1(真实世界) : 在哪里采取行动 a 和 y 观察
2.世界2(反事实世界) : 行动 a 没有采取(但其他一切都是一样的)
因果效应是在现实世界中获得的 y 值与在虚拟世界中获得的 y 值之间的差异
在形式上,因果效应是指 a 中 y 因单位介入性变化而改变的幅度:
为了估计效果,金标准是进行一个随机化实验,其中一个随机化的单位子集被采取行动(a = 1) ,另一个子集不是(a=0).这些子集近似于不相交的真实世界和反事实世界,随机化确保了这两个子集之间没有系统的差异(“保持其他所有东西不变”)。
然而,进行随机实验并不总是可行的。要回答因果问题,我们常常需要依靠观察或记录的数据。这些观察到的数据由于相互关联而有偏差,因此在哪些单元受到影响,哪些单元没有受到影响方面存在系统性差异。例如,假日期间可能会部署新的营销活动,可能只对高活跃度用户使用新功能,或者老年患者更有可能接受新药,等等。因果推理方法的目标是从数据中去除这种相关性和混淆,并估计一个行为的真实效果,正如上面的等式所给出的。
预测与因果推理的区别
因果推理的两个基本挑战
我们无法观察反事实的世界
- 不能直接计算因果效应
- 必须估计反事实
- 验证方面的挑战
多个因果机制可以适用于单个数据分布
- 仅仅数据不足以进行因果推理
- 需要领域知识和假设
因为没有可以与估计值进行比较的地面真实性测试数据集,因果推断需要一系列原则性步骤来实现良好的估计值。
让我们通过一个示例数据集来演示这四个步骤。本教程要求您下载两个库: DoWhy 和 EconML。两者都可以通过以下命令安装:
pip install dowhy econml
# 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,
stddev_treatment_noise=10)
最上面知乎那位老哥的注释
Conda 环境最好是3.9版本,3.7版本会有点问题
from dowhy import CausalModel
import dowhy.datasets
# Load some sample data
data = dowhy.datasets.linear_dataset(beta=10, # beta 表示真实的因果效应
num_common_causes=5, # 混杂因子,用 W 表示,作用于干预变量和结果变量
num_instruments=2, # 工具变量,用 Z 表示,作用于干预变量(间接影响结果)
num_effect_modifiers=1, # 效果修改变量,用 X 表示,作用于结果变量
num_samples=10000, # 样本数量
treatment_is_binary=True, # 干预为二元变量,用 v 表示
num_discrete_common_causes=1)
df = data["df"] # DoWhy 使用 pandas 的 dataframe 来载入数据
print(df.head())
print(data["dot_graph"]) # 还可以输出 gml_graph,内容一致只是表达形式不同
## print(df.head())
Z0 Z1 W0 W1 W2 W3 W4 v0 \
0 1.0 0.071969 -0.205272 0.180014 -0.187006 -1.299736 -0.271925 True
1 0.0 0.322195 1.194945 0.526213 0.357136 -0.917636 1.722885 True
2 0.0 0.589446 0.767012 -1.466300 1.531776 -1.219019 0.139352 True
3 0.0 0.096678 1.203009 -1.334037 0.459784 0.271902 0.020540 True
4 0.0 0.000788 -0.831644 0.347659 -1.181528 -1.073900 1.280033 False
## gml_graph
y propensity_score
0 2.848172 0.458798
1 9.909028 0.989102
2 4.946410 0.879141
3 11.863850 0.989545
4 -7.257158 0.642876
digraph {v0->y;W0-> v0; W1-> v0; W2-> v0; W3-> v0; W4-> v0;Z0-> v0; Z1-> v0;W0-> y; W1-> y; W2-> y; W3-> y; W4-> y;}
一,模型
第一步是将我们的领域知识编码成一个因果模型,通常用图表来表示。因果推理分析的最终结果在很大程度上取决于输入假设,因此这一步非常重要。为了估计因果效应,最常见的问题涉及指定两类变量:
混杂因素(common _ causes) : 这些是导致行为和结果的变量。因此,任何观察到的行为和结果之间的相关性可能仅仅是由于混淆变量,而不是由于行为和结果之间的任何因果关系。
Instrumental Variables (instruments)工具性变量: 这些是特殊的变量,导致行为,但不直接影响结果。此外,他们不受任何影响结果的变量的影响。如果使用正确,仪器变量可以帮助减少偏倚。
# 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"],
instruments=data["instrument_names"])
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")
二,鉴别Identification
提供领域知识的两种方式(或者通过混杂因素和工具变量的命名变量集,或者通过因果图)对应于一个底层的因果图。给定一个因果图和一个目标量(例如,a 对 b 的影响) ,识别的过程是检查目标量是否能被给定观察变量估计。重要的是,标识只考虑观察数据中可用的变量的名称; 它不需要访问数据本身。与上述两类变量相关,因果推理的识别方法主要有两种。
- Backdoor criterion (or more generally, adjustment sets)后门准则(或者更广泛地说,调整集合) : 如果行动 a 和结果 y 的所有共同原因都被观察到,那么后门准则意味着可以通过条件作用于所有共同原因来确定因果效应。这是一个简化的定义(关于正式定义,请参阅 CausalML 书籍的第3章)。
-
Instrumental variable (IV) identification工具变量(IV)识别: 如果有一个工具变量可用,那么我们可以估计效果,即使任何(或没有)的共同原因的行动和结果是不观察。第四种认定利用工具只对行为产生直接影响的事实,因此工具对结果的影响可以分为两个连续的部分: 工具对行为的影响和行为对治疗的影响。然后,它依赖于估计工具对行动和结果的影响来估计行动对结果的影响。对于二进制仪器,效应估计是由,
# II. Identify causal effect and return target estimands
identified_estimand = model.identify_effect(proceed_when_unidentifiable=True)
print(identified_estimand)
III. 估计Estimation
顾名思义,估计步骤包括建立一个统计估计器,该估计器可以计算目标估计量并在前一步中识别。许多因果推理的估计量已经被提出。DoWhy 实现了一些标准的估计器,而 EconML 实现了一组使用机器学习的强大估计器。
我们给出了使用 DoWhy 进行倾向评分分层的示例,以及使用 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)
四、驳斥Refutation
最后,检查估计的稳健性可能是因果分析中最重要的步骤。我们使用步骤1-3获得了一个估计值,但是每一步都可能做出了某些假设,这些假设可能并不正确。由于没有适当的验证“测试”集,这一步依赖于反驳测试,这些测试试图用好的估计器的性质来反驳所得估计值的正确性。例如,反驳测试(placebo _ treatment _ refuter)检查当行为变量被独立于所有其他变量的随机变量替换时,估计器是否返回0的估计值。
# IV. Refute the obtained estimate using multiple robustness checks.
refute_results = model.refute_estimate(identified_estimand, estimate,
method_name="random_common_cause")
回顾一下前面
模型:DoWhy使用因果关系图对每个问题建模。DoWhy的当前版本支持两种图形输入格式:gml(首选)和dot。图中可能包含了变量之间因果关系的先验知识,但DoWhy不做任何直接的假设。
标识:使用输入图,DoWhy根据图形模型找到所有可能的方法来标识期望的因果关系。它使用基于图的标准和do-calculus来寻找潜在的方法,找到能够识别因果关系的表达式
估计:DoWhy使用匹配或工具变量等统计方法估计因果效应。DoWhy的当前版本支持基于倾向性分层或倾向性评分匹配的估计方法,这些方法侧重于估计处理任务,以及侧重于估计响应面的回归技术。
验证:最后,DoWhy使用不同的robustness methods(鲁棒性方法)验证因果效应的有效性。
DoWhy 支持两种格式来提供因果图: gml (preferred)和 dot。在加载数据之后,我们使用 DoWhy 中的四个主要操作: 建模、估计、识别和反驳:
# I. Create a causal model from the data and given graph.
model = CausalModel(
data=data["df"],
treatment=data["treatment_name"],
outcome=data["outcome_name"],
graph=data["gml_graph"])
# II. Identify causal effect and return target estimands
identified_estimand = model.identify_effect()
# III. Estimate the target estimand using a statistical method.
estimate = model.estimate_effect(identified_estimand,
method_name="backdoor.propensity_score_matching")
# IV. Refute the obtained estimate using multiple robustness checks.
refute_results = model.refute_estimate(identified_estimand, estimate,
method_name="random_common_cause")
和其他包一起连用
The DoWhy+EconML solution
我们将使用 DoWhy + EconML 库进行因果推理。DoWhy 为这四个步骤提供了一个通用 API,EconML 为估计步骤提供了高级估计器。
DoWhy 允许您可视化、形式化和测试他们所做的假设,这样您就可以更好地理解分析,避免得出不正确的结论。它通过明确地侧重于假设,并尽可能对假设的有效性进行自动检查来做到这一点。正如你将看到的,DoWhy 的威力在于它提供了一个正式的因果框架来编码领域知识,并且它可以运行自动的稳健性检查来验证任何估计方法的因果估计。
此外,当数据变得高维时,我们需要能够处理已知混淆的专门方法。在这里,我们使用 EconML 来实现许多最先进的因果估计方法。这个软件包包含了所有技术的通用 API,每项技术都被实现为一系列的机器学习任务,允许使用任何现有的机器学习软件来解决这些子任务,允许你插入你已经熟悉的机器学习模型,而不是学习一个新的工具包。EconML 的强大之处在于,您现在可以像运行线性回归或随机森林一样轻松地实现最先进的因果推理。
总之,DoWhy + EconML 通过提供最先进的端到端因果推断框架,包括最新的因果估计和自动鲁棒性过程,使得回答 what if 问题变得容易得多。
神秘的数据集: 你能找出是否存在因果关系吗
为了遍历这四个步骤,让我们考虑一下神秘数据集问题。假设给你一些关于治疗和结果的数据。你能确定是治疗导致了结果,还是相关性纯粹是由于另一个共同的原因?
import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
import math
import dowhy.datasets, dowhy.plotter
rvar = 1 if np.random.uniform() > 0.2 else 0
is_linear = False # A non-linear dataset. Change to True to see results for a linear dataset.
data_dict = dowhy.datasets.xy_dataset(10000, effect=rvar,
num_common_causes=2,
is_linear=is_linear,
sd_error=0.2)
df = data_dict['df']
print(df.head())
dowhy.plotter.plot_treatment_outcome(df[data_dict["treatment_name"]], df[data_dict["outcome_name"]],
df[data_dict["time_val"]])