【Python实战因果推断】32_双重差分3

目录

Diff-in-Diff with OLS

Diff-in-Diff with Fixed Effects

Multiple Time Periods


Diff-in-Diff with OLS

尽管您可以通过手工计算平均值或取差值来实现 DID,但如果不包含相当数量的线性回归,这就不是一个值得尊敬的因果推理章节。毫不奇怪,你可以用饱和回归模型得到完全相同的 DID 估计值。首先,让我们按城市和时期(干预后和干预前)对每日数据进行分组。然后,对于每个城市和时期的组合,您可以得到平均每日下载次数。我还会得到每个时期的开始日期和每个城市的干预状态。开始日期并不用于估算,但它有助于了解干预发生的时间:

 did_data = (mkt_data
 .groupby(["city", "post"])
 .agg({"downloads":"mean", "date": "min", "treated": "max"})
 .reset_index())
 did_data.head()

使用此城市按周期数据集,您可以估计以下线性模型:

Y_{it}=\beta_0+\beta_1D_i+\beta_2Post_t+\beta_3D_iPost_t+e_{it}

参数估计值 β3 将是 DID 估计值。要知道为什么会这样,请注意 β0 是控制的基线。在这种情况下,β0 是 2021-05-15 之前控制城市的下载量水平。如果打开受治疗城市虚拟值,则得到 β0 + β1。因此,β0 + β1 是受治疗城市的基线,也是干预前的基线。β1 只是治疗城市与对照城市之间的基线差异。如果关闭干预假值,打开干预后假值,则得到 β0 + β2,即干预后对照城市的水平。β2 是对照组的趋势。这是对照组从干预前到干预后的增长幅度。

概括地说,β1 是指从对照组到干预组的增量,β2 是指从干预前到干预后的增量。最后,如果同时打开治疗前和治疗后的虚拟变量,则得到 β0+ β1+ β2+ β3。这是干预后受治疗城市的水平,也就是说,β3 是指从受治疗城市到对照城市、从干预前到干预后时期所得到的结果增量。换句话说,这就是差分估计法:

 import statsmodels.formula.api as smf
 smf.ols(
 'downloads ~ treated*post', data=did_data
 ).fit().params["treated:post"]
 
 0.691735953640

Diff-in-Diff with Fixed Effects

另一种理解 DID 的方法是时间和单位固定效应模型(双向固定效应或 TWFE)。在该模型中,有干预效应 τ、单位和时间固定效应 αi 和 γt:

Y_{it}=\tau W_{it}+\alpha_{i}+\gamma_{t}+e_{it} .

为了整理,我在这里使用W_{it}=D_iPost_t

如果您对该模型进行估计,与 W 相关的参数估计值将与您之前得到的 DID 估计值相匹配,并恢复 ATT。为此您可以通过使用虚拟变量或去数据含义来估计固定效应。这里,为了简单起见,我们只使用虚拟变量的方法。也就是说,我们用 C(city)和 C(post)来包含城市和时期虚拟变量。此外,您还需要将处理过的虚拟数据和职位虚拟数据相乘来创建 W。请记住,"*"运算符可以创建两个项之间的交互作用和项本身的交互作用。由于您只需要交互作用,因此需要使用 : 运算符:

  m = smf.ols('downloads ~ treated:post + C(city) + C(post)',
 data=did_data).fit()
 m.params["treated:post"]
 
 0.691735953640

再一次,你得到了完全相同的参数估计。

Multiple Time Periods

典型的 DID 设置要求只有四个数据单元格:干预前、干预后、治疗组和对照组。但它并不要求将干预前和干预后的时间段合并为一个区组。典型的 DID 只要求有所谓的区块设计:一组从未接受治疗的单元和一组最终在同一时间段接受治疗的单元。也就是说,你不能让干预在不同时刻向单位推出(你很快就会了解到)。您正在使用的营销示例正是这种格式,这意味着您不必按照干预前和干预后的时间段进行汇总。您只需按原样使用即可。

您可以在下图中直观地看到这种分块设计,该图绘制了每个城市随时间变化的干预分配情况。图中还显示了结果在不同时间段的变化情况,这样你就能更好地理解 DID 所关注的问题。也就是说,DID 试图观察干预措施实施后,治疗组和对照组之间的差异是否会扩大:

要利用这些分类数据得出 DID 估计值,可以使用与之前完全相同的公式。也就是说,您既可以将结果与处理后虚拟变量和处理后虚拟变量之间的交互作用进行回归,也可以将结果与处理后虚拟变量和处理后虚拟变量之间的交互作用进行回归:

 m = smf.ols('downloads ~ treated*post', data=mkt_data).fit()
 m.params["treated:post"]
 
 0.6917359536407226

或者您可以使用固定效果规范:

 m = smf.ols('downloads ~ treated:post + C(city) + C(date)',
 data=mkt_data).fit()
 m.params["treated:post"]
 
 0.691735953640

我刚刚展示了一系列获得完全相同的 DID 估计值的方法。我希望通过这样做,你能从所有方法中获得启发,从而增加你理解发生了什么的机会。但是,如果你仔细观察,我故意隐藏了你刚才运行的回归的置信区间。这是因为这些回归的置信区间可能是错误的。

因果推断是指通过观察数据中的相关性来研究变量间的因果关系。在Python中,有几个库可以用于因果推断,其中最常用的是DoWhy和CausalImpact。 DoWhy是一个用于因果推断Python库,它基于因果图(causal graph)的概念来推断因果关系。它提供了一个简单而灵活的框架,可用于估计因果效应、进行因果推断和处理反事实问题。DoWhy支持多种因果推断方法,包括倾向得分匹配、倾向得分加权、双重差分等。 另一个常用的因果推断工具是CausalImpact。CausalImpact是一个用于因果效应估计的Python库,专门用于分析时间序列数据。它基于贝叶斯方法来估计因果效应,并提供了一个易于使用的界面来评估一个事件对时间序列数据的影响。 以下是使用DoWhy进行因果推断的示例代码: ```python import dowhy from dowhy import CausalModel # 创建一个因果模型 model = CausalModel( data=df, # 数据集 treatment='treatment_variable', # 治疗变量 outcome='outcome_variable', # 结果变量 common_causes=['common_cause_1', 'common_cause_2'] # 其他共同原因 ) # 估计因果效应 identified_estimand = model.identify_effect(proceed_when_unidentifiable=True) causal_estimate = model.estimate_effect(identified_estimand, method_name="backdoor.propensity_score_matching") # 因果效应的可视化 model.visualize_effect(identified_estimand, causal_estimate) # 进行因果推断 estimate = model.refute_estimate(identified_estimand, causal_estimate, method_name="random_common_cause") ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

水木流年追梦

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值