观测数据中的因果推理

2024-06-06 17:00:27 发布

您现在位置:Python中文网/ 问答频道 /正文

我正在使用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. 这是进行分析的正确方法吗

  2. 共同原因意味着什么,如何选择

  3. 我如何解释结果?有什么把握


Tags: dfsiteloginmoviesthisnravgcausal
1条回答
网友
1楼 · 发布于 2024-06-06 17:00:27

让我们逐一回答你的问题

一,。这条路对吗

是的,您的代码片段是正确的,假设您希望通过对nr_loginavg_movies进行条件化来估计tenureChurn的因果效应

但是,此方法将输出一个数据帧,其中包含结果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中所述(也请参见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")

也就是说,根据您的数据集,可能还有其他更适合的估计方法。例如,如果考虑到常见原因的可能值,其中一个治疗值不太可能出现,则“加权”法预计会有较高的方差。此外,如果数据有限,此方法可能无法很好地用于连续处理,因为它是一种非参数方法,通常会有很大的方差。在这些情况下,您可以使用其他估算方法,如使用参数假设的double ML,以减少估算中的方差(以可能的偏差为代价)。您可以像这样调用double 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":{}
                                     })

二,。如何选择共同原因

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

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

三,。如何解释结果及其不确定性

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

为了估计不确定性,您可以估计置信区间和/或进行反驳测试。置信区间将告诉您统计不确定性(大致上,如果您获得新的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")

相关问题 更多 >