观察数据中的因果推断

Jam*_*lor -1 python inference causality

我正在使用python包DoWhy来查看基于此站点的tenure和churn之间是否存在因果关系。

# 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'])
Run Code Online (Sandbox Code Playgroud)

我还有许多其他变量。

  1. 这是进行分析的正确方法吗?

  2. 常见原因是什么意思,如何选择它们?

  3. 我如何解释结果以及如何确定?

小智 5

让我们一一回答您的问题。

1. 这是正确的方法吗?

是的,您的代码段是正确的,假设你要估计的因果关系tenureChurn上调理nr_loginavg_movies

然而,此方法将输出包含结果的介入值的数据帧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()
Run Code Online (Sandbox Code Playgroud)

但是,要计算平均因果效应,更直接的程序是针对要计算效应do的两个处理值运行该方法两次(典型值是比较处理 = 1 与 0)。结果代码将如下所示,如示例笔记本中所述(另请参阅该方法的文档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()
Run Code Online (Sandbox Code Playgroud)

还有一种使用主 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")
Run Code Online (Sandbox Code Playgroud)

也就是说,根据您的数据集,可能还有其他更适合的估计方法。例如,如果考虑到常见原因的可能值,处理值之一不太可能,则“加权”方法预计具有高方差。此外,如果您的数据有限,此方法可能不适用于连续处理,因为它是一种非参数方法,通常具有高方差。在这些情况下,您可以使用其他估计器方法,例如使用参数假设的双 ML 来减少估计中的方差(以可能的偏差为代价)。您可以像这样调用 double-ML 或其他高级 EconML 估计器(本笔记本中的完整示例):

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":{}
                                     })
Run Code Online (Sandbox Code Playgroud)

2.如何选择common_causes?

常见原因是导致治疗和结果的变量。因此,治疗和结果之间的相关性可能是由于治疗的因果效应,或者仅仅是由于常见原因的影响(经典的例子是冰淇淋销售与游泳池会员资格相关,但一个不会导致另一个;炎热的天气是这里的常见原因)。因果推理的目标是以某种方式解开常见原因的影响,只返回治疗的效果。形式上,因果效应是当所有常见原因保持不变时治疗对结果的影响。有关更多信息,请查看有关因果推理的教程

因此,在您的示例中,您希望包含所有变量,这些变量既会导致客户拥有高任期并减少他们流失的机会(例如,他们的每月使用量、对平台的信任等)。这些是需要包含在模型中的常见原因或混杂因素。

3. 如何解释结果及其不确定性?

如上所述,因果效应的标准解释是churn当治疗改变 1 个单位时结果的变化 ( )。但是,对于连续变量,这只是一个约定:您可以将因果效应定义为结果在任何两个治疗值上的变化。

为了估计不确定性,您可以估计置信区间和/或进行反驳检验。置信区间会告诉你统计的不确定性(粗略地说,如果给你一个新的 iid 数据样本,你的估计会改变多少?)。反驳测试将量化由于因果假设引起的不确定性(如果您错过了指定重要的常见原因,估计会改变多少?)。

这是一个例子。您可以在此处找到有关反驳方法的更多信息

# 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")
Run Code Online (Sandbox Code Playgroud)