观察数据中的因果推断
Causal Inference in observational data
我正在使用 python 包 DoWhy
来查看基于 this site.
的任期和客户流失之间是否存在因果关系
# TREATMENT = TENURE
causal_df = df.causal.do('tenure',
method = 'weighting',
variable_types = {'Churn': 'd', 'tenure': 'c', 'nr_login', 'c','avg_movies': 'c'
},
outcome='Churn',common_causes=['nr_login':'c','avg_movies': 'c'])
我还有一些其他变量。
这是正确的分析方法吗?
常见原因是什么意思,如何选择?
我如何解释结果以及确定性如何?
让我们一一解答您的问题。
1。这是正确的方法吗?
是的,你的代码片段是正确的,假设你想通过以 nr_login
和 avg_movies
为条件来估计 tenure
和 Churn
的因果效应。
然而,此方法将输出一个数据帧,其中包含结果 Churn
的 干预 值。也就是说,流失变量的值就好像任期已经独立于指定的常见原因而改变一样。如果处理 tenure
是离散的,您可以绘制一个简单的图来可视化 tenure
的不同值的影响。类似于:
causal_df = df.causal.do('tenure',
method = 'weighting',
variable_types = {'Churn': 'd', 'tenure': 'd', 'nr_login', 'c','avg_movies': 'c'},
outcome='Churn',common_causes=['nr_login':'c','avg_movies': 'c']).groupby('tenure').mean()
但是,要计算平均因果效应,更直接的过程是 运行 do
方法两次用于计算效应的两个治疗值(典型的价值是比较治疗= 1与0)。生成的代码如下所示,如 example notebook (also see the docs 中 do
方法所述:
df_treatment1 = df.causal.do({'tenure': 1},
method = 'weighting',
variable_types = {'Churn': 'd', 'tenure': 'd', 'nr_login', 'c','avg_movies': 'c'},
outcome='Churn',common_causes=['nr_login':'c','avg_movies': 'c'])
df_treatment0 = df.causal.do({'tenure': 0},
method = 'weighting',
variable_types = {'Churn': 'd', 'tenure': 'd', 'nr_login', 'c','avg_movies': 'c'},
outcome='Churn',common_causes=['nr_login':'c','avg_movies': 'c'])
causal_effect = (df_treatment1['churn'] - df_treatment0["churn"]).mean()
还有一种使用主要 DoWhy API.
实现相同结果的等效方法
model= CausalModel(
data=df,
treatment='tenure',
outcome='churn',
common_causes=['nr_login', 'avg_movies'])`
identified_estimand = model.identify_effect()
model.estimate_effect(identified_estimand, method="backdoor.propensity_score_weighting")
也就是说,根据您的数据集,可能还有其他更适合的估计方法。例如,如果给定常见原因的可能值,其中一个治疗值不太可能,则 "weighting" 方法预计具有高方差。此外,如果您的数据有限,则此方法可能不适用于连续处理,因为它是一种非参数方法,通常具有较高的方差。在这些情况下,您可以使用其他估计器方法,例如使用参数假设的双 ML 来减少估计中的方差(以可能的偏差为代价)。您可以像这样调用双 ML 或其他高级 EconML 估计器(this notebook 中的完整示例):
model.estimate_effect(identified_estimand,
method_name="backdoor.econml.dml.DMLCateEstimator",
control_value = 0,
treatment_value = 1,
confidence_intervals=False,
method_params={"init_params":
{'model_y':GradientBoostingRegressor(),
'model_t': GradientBoostingRegressor(),
"model_final":LassoCV(),
'featurizer':PolynomialFeatures(degree=1,
include_bias=True)
},
"fit_params":{}
})
2。如何选择common_causes?
常见原因是导致治疗和结果的变量。因此,治疗和结果之间的相关性可能是由于治疗的因果效应,或者仅仅是由于常见原因的影响(典型的例子是冰淇淋销售与游泳池会员资格相关,但一个不会导致另一个; 炎热的天气是这里的常见原因)。因果推理的目标是以某种方式解开常见原因的影响,并且仅 return 处理的效果。形式上,因果效应是当所有常见原因保持不变时治疗对结果的影响。有关更多信息,请查看此 tutorial 关于因果推理)
因此,在您的示例中,您希望包括所有变量,这些变量既可以导致客户拥有较高的使用期限,又可以减少他们流失的机会(例如,他们的每月使用量、对平台的信任度等)。这些是需要包含在模型中的常见原因或混杂因素。
3。如何解释结果及其不确定性?
如上所述,因果效应的标准解释是当治疗改变 1 个单位时结果的变化 (churn
)。但是,对于连续变量,这只是一个约定:您可以将因果效应定义为治疗的任何两个值的结果变化。
为了估计不确定性,您可以估计置信区间 and/or 进行反驳检验。置信区间会告诉您有关统计不确定性的信息(粗略地说,如果给您一个新的 i.i.d. 数据样本,您的估计值会发生多少变化?)。反驳测试将量化因果假设引起的不确定性(如果您没有指定一个重要的共同原因,估计会发生多少变化?)。
举个例子。您可以找到更多关于反驳方法的信息 here.
# Confidence intervals
est = model.estimate_effect(identified_estimand, method="backdoor.propensity_score_weighting",
confidence_intervals=True)
# Refutation test by adding a random common cause
model.refute_estimate(identified_estimand, est, method_name="random_common_cause")
我正在使用 python 包 DoWhy
来查看基于 this site.
# TREATMENT = TENURE
causal_df = df.causal.do('tenure',
method = 'weighting',
variable_types = {'Churn': 'd', 'tenure': 'c', 'nr_login', 'c','avg_movies': 'c'
},
outcome='Churn',common_causes=['nr_login':'c','avg_movies': 'c'])
我还有一些其他变量。
这是正确的分析方法吗?
常见原因是什么意思,如何选择?
我如何解释结果以及确定性如何?
让我们一一解答您的问题。
1。这是正确的方法吗?
是的,你的代码片段是正确的,假设你想通过以 nr_login
和 avg_movies
为条件来估计 tenure
和 Churn
的因果效应。
然而,此方法将输出一个数据帧,其中包含结果 Churn
的 干预 值。也就是说,流失变量的值就好像任期已经独立于指定的常见原因而改变一样。如果处理 tenure
是离散的,您可以绘制一个简单的图来可视化 tenure
的不同值的影响。类似于:
causal_df = df.causal.do('tenure',
method = 'weighting',
variable_types = {'Churn': 'd', 'tenure': 'd', 'nr_login', 'c','avg_movies': 'c'},
outcome='Churn',common_causes=['nr_login':'c','avg_movies': 'c']).groupby('tenure').mean()
但是,要计算平均因果效应,更直接的过程是 运行 do
方法两次用于计算效应的两个治疗值(典型的价值是比较治疗= 1与0)。生成的代码如下所示,如 example notebook (also see the docs 中 do
方法所述:
df_treatment1 = df.causal.do({'tenure': 1},
method = 'weighting',
variable_types = {'Churn': 'd', 'tenure': 'd', 'nr_login', 'c','avg_movies': 'c'},
outcome='Churn',common_causes=['nr_login':'c','avg_movies': 'c'])
df_treatment0 = df.causal.do({'tenure': 0},
method = 'weighting',
variable_types = {'Churn': 'd', 'tenure': 'd', 'nr_login', 'c','avg_movies': 'c'},
outcome='Churn',common_causes=['nr_login':'c','avg_movies': 'c'])
causal_effect = (df_treatment1['churn'] - df_treatment0["churn"]).mean()
还有一种使用主要 DoWhy API.
实现相同结果的等效方法model= CausalModel(
data=df,
treatment='tenure',
outcome='churn',
common_causes=['nr_login', 'avg_movies'])`
identified_estimand = model.identify_effect()
model.estimate_effect(identified_estimand, method="backdoor.propensity_score_weighting")
也就是说,根据您的数据集,可能还有其他更适合的估计方法。例如,如果给定常见原因的可能值,其中一个治疗值不太可能,则 "weighting" 方法预计具有高方差。此外,如果您的数据有限,则此方法可能不适用于连续处理,因为它是一种非参数方法,通常具有较高的方差。在这些情况下,您可以使用其他估计器方法,例如使用参数假设的双 ML 来减少估计中的方差(以可能的偏差为代价)。您可以像这样调用双 ML 或其他高级 EconML 估计器(this notebook 中的完整示例):
model.estimate_effect(identified_estimand,
method_name="backdoor.econml.dml.DMLCateEstimator",
control_value = 0,
treatment_value = 1,
confidence_intervals=False,
method_params={"init_params":
{'model_y':GradientBoostingRegressor(),
'model_t': GradientBoostingRegressor(),
"model_final":LassoCV(),
'featurizer':PolynomialFeatures(degree=1,
include_bias=True)
},
"fit_params":{}
})
2。如何选择common_causes?
常见原因是导致治疗和结果的变量。因此,治疗和结果之间的相关性可能是由于治疗的因果效应,或者仅仅是由于常见原因的影响(典型的例子是冰淇淋销售与游泳池会员资格相关,但一个不会导致另一个; 炎热的天气是这里的常见原因)。因果推理的目标是以某种方式解开常见原因的影响,并且仅 return 处理的效果。形式上,因果效应是当所有常见原因保持不变时治疗对结果的影响。有关更多信息,请查看此 tutorial 关于因果推理)
因此,在您的示例中,您希望包括所有变量,这些变量既可以导致客户拥有较高的使用期限,又可以减少他们流失的机会(例如,他们的每月使用量、对平台的信任度等)。这些是需要包含在模型中的常见原因或混杂因素。
3。如何解释结果及其不确定性?
如上所述,因果效应的标准解释是当治疗改变 1 个单位时结果的变化 (churn
)。但是,对于连续变量,这只是一个约定:您可以将因果效应定义为治疗的任何两个值的结果变化。
为了估计不确定性,您可以估计置信区间 and/or 进行反驳检验。置信区间会告诉您有关统计不确定性的信息(粗略地说,如果给您一个新的 i.i.d. 数据样本,您的估计值会发生多少变化?)。反驳测试将量化因果假设引起的不确定性(如果您没有指定一个重要的共同原因,估计会发生多少变化?)。
举个例子。您可以找到更多关于反驳方法的信息 here.
# Confidence intervals
est = model.estimate_effect(identified_estimand, method="backdoor.propensity_score_weighting",
confidence_intervals=True)
# Refutation test by adding a random common cause
model.refute_estimate(identified_estimand, est, method_name="random_common_cause")