DoWhy | An end-to-end library for causal inference
Getting started with DoWhy: A simple example
使用因果推理的四个步骤来动手估计因果效应:建模model
、识别identify
、估计 estimate
和反驳 refute
。
假设我们想要找到采取行动A对结果y的因果影响,要定义因果影响,考虑两个世界:
因果效应是在现实世界与反事实世界中Y 值之间的差异。换句话说,其他一切都保持不变,当 A 改变导致 Y 改变时,A 是Y的原因. 在保持其他一切不变的情况下更改 A 称为干预,并由符号 d o ( A ) do(A) do(A) 表示.
形式上,将因果效应定义为结果(Y
) 因 原因(A
) 的单位干预变化而变化的幅度:
E [ Y ∣ d o ( A = 1 ) ] − E [ Y ∣ d o ( A = 0 ) ] E[Y|do(A=1)] - E[Y|do(A=0)] E[Y∣do(A=1)]−E[Y∣do(A=0)]
为了估计效果,黄金标准是进行一个随机实验,其中一半做动作(A=1)而另一半不做动作(A=0)。 这些子集近似于模拟真实世界和反事实世界,随机化两个子集之间没有系统差异(“保持其他一切不变”,即除了A没有其他不同)。然而,进行随机实验并不总是可行的。 为了回答因果问题,我们通常需要依靠观察或记录的数据。 观察到的数据因相关性和未观察到的混杂而存在偏差,因此容易存在系统差异。 例如,新的营销活动可能会在假日季节部署,新功能可能仅适用于高活动用户,或者年龄较大的患者可能更有可能接受新药,等等。 因果推理方法的目标是从数据中消除这些相关性和混淆,并估计一个动作的真实效果,如上面的等式所示。
单个数据分布 可能有多个因果机制
下载两个库: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)
会提示 stddev_treatment_noise=10
有错,删去
# 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)
treatment_name
指定行动编号outcome_name
指定结果编号common_causes_names
对行动和结果同时有直接影响的编号instrument_names
只对行动有直接影响的编号gml_grapg
定义了边和点将数据集中的数据转换成图,涉及指定两种类型的变量:
混杂因素(common_causes
):会同时对行动和结果产生影响的变量。
因此,任何观察到的行动与结果之间的相关性都可能仅仅是由于混杂变量,而不是由于行动与结果之间的任何因果关系。
工具变量(instruments
):这些是不直接影响结果,但是会对行动产生影响的特殊变量。
它们不受任何影响结果的变量的影响。 如果以正确的方式使用,工具变量可以帮助减少偏差。
从数据和领域知识中建图
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的影响)的情况下,识别的过程是检查目标量是否可以根据观察变量估计出来。重要的是,标识只考虑被观测数据中可用变量的名称;它不需要访问数据本身。针对上述两类变量,因果推理主要有两种识别方法。
identified_estimand = model.identify_effect(proceed_when_unidentifiable=True)
print(identified_estimand)
顾名思义,估计步骤涉及构建一个统计估计器,该估计器可以计算上一步中确定的目标估计值。 已经提出了许多用于因果推断的估计量。 DoWhy 实现了一些标准估计器,而 EconML 实现了一组使用机器学习的强大估计器。
分别使用 DoWhy 使用倾向得分分层的示例&使用 EconML 的基于机器学习的方法,称为 Double-ML
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)
最后,检查估计的稳健性可能是因果分析中最重要的一步。
我们使用步骤 1-3 获得了一个估计值,但每个步骤都可能做出了某些可能不正确的假设。
在没有适当的验证数据——“测试”集的情况下,此步骤依赖于反驳测试,该测试旨在使用良好估计器的属性来反驳所获得估计的正确性。
例如,反驳测试 (placebo_treatment_refuter) 检查当动作变量被随机变量替换时,估计器是否返回估计值 0,与所有其他变量无关。
refute_results = model.refute_estimate(identified_estimand, propensity_strat_estimate,
method_name="placebo_treatment_refuter")
print(refute_results)