【Python实战因果推断】44_合成控制4

目录

Synthetic Control with Covariants


Synthetic Control with Covariants

通常,合成控制只使用控制单元的前干预结果作为预测 \bar{Y}_{tr} 的特征。这是因为这些特征往往是您所掌握的最具预测性的特征。但是,如果您认为一些额外的协变量具有很好的预测能力,您可能希望在模型中加入这些协变量。不过这种情况比较少见,所以如果时间不够,可以跳过这一部分。

假设您设法获得了主要竞争对手的每日下载量数据,并根据市场规模(comp_down load_pct)对这些数据进行了归一化处理。您认为这个协变量可以很好地预测 \bar{Y}_{tr},因此希望将其纳入合成控制模型:

 df_norm_cov = (pd.read_csv("./data/online_mkt_cov.csv")
 .astype({"date":"datetime64[ns]"}))
 df_norm_cov.head()

用数学符号表示,您希望构建一个合成控制,使权重 w_i 不仅乘以 y_{co},还乘以这个额外的协变量 x_{co},以近似 \bar{Y}_{tr}。这里的问题是,x_{co}y_{co} 的比例可能完全不同,或者其中一个比另一个更具预测性,这就是为什么在求解 SC 优化问题之前,需要将包括 y_{co} 在内的每个协变量乘以比例因子 v。为了考虑到这一点,可以用协变量 X 来重写目标,将 y_{co} 视为另一个协变量:

\begin{aligned}\widehat{w}^{sc}&=\underset{\omega}{\operatorname*{argmin}} \left|\left|\overline{\mathbf{y}}_{pre,tr}-\sum v_{k}^{*}\mathbf{X}_{k, pre, co}\omega_{co}\right|\right|^{2}\\&\mathrm{s.t}\quad\sum\omega_{i}=1\mathrm{~and~}\omega_{i}>0\mathrm{~}\forall\mathrm{~}i\end{aligned}

然而,这个目标并没有告诉你如何找到最优 v。要做到这一点,你必须将整个合成控制打包到另一个优化目标中。如果听起来很复杂,不用担心。用代码来理解要容易得多。首先,让我们为两个协变量 comp_download_pct 和 Y_{pre,co}、app_download_pct 创建 X 矩阵:

 from toolz import partial
 reshaper = partial(reshape_sc_data,
 df=df_norm_cov,
 geo_col="city",
 time_col="date",
 tr_geos=treated,
 tr_start=str(tr_period))
 y_pre_co, y_pre_tr, y_post_co, y_post_tr = reshaper(
 y_col="app_download_pct"
 )
 x_pre_co, _, x_post_co, _ = reshaper(y_col="comp_download_pct")

接下来,让我们编写一个函数,当给定一个 vs 列表(每个协变量一个)时,返回合成控制权重和优化损失。请记住,您可以使用 .loss_ 访问拟合 SyntheticControl 模型的目标损失。

要检查是否有效,可以传递 [1, 0] 作为 vs 和 [y_pre_co, x_pre_co] 作为协变量列表。由于在这种情况下额外的协变量权重为零,因此您应该得到原始的合成控制:

 def find_w_given_vs(vs, x_co_list, y_tr_pre):
 X_times_v = sum([x*v for x, v in zip(x_co_list, vs)])
 
 model = SyntheticControl()
 model.fit(X_times_v, y_tr_pre)
 
 return {"loss": model.loss_, "w": model.w_}
 
 find_w_given_vs([1, 0],
 [y_pre_co, x_pre_co],
 y_pre_tr.mean(axis=1)).get("w").round(3)
 
 array([-0. , -0. , 0. , -0. , -0. , -0. , 0.084, 0.039,
 0.085, 0.003, -0. , -0. , -0. , -0. , -0. , 0. ,
 0.062, 0.121, -0. , 0.072, -0. , 0. , -0. , 0. ,
 -0. , -0. , 0. , -0. , -0. , 0. , -0. , 0.095,
 0. , -0. , 0. , 0.022, 0.116, -0. , 0.068, 0.046,
 -0. , -0. , -0. , 0.088, 0. , 0.098, -0. ])

最后,可以将 find_w_given_vs 封装在一个函数中,该函数只接收 vs 数组并返回优化损失。然后,你可以将这个函数传递给 scipy minimize 函数,它会反复寻找最佳 vs 并返回给你:

 from scipy.optimize import minimize
 def v_loss(vs):
 return find_w_given_vs(vs,
 [y_pre_co, x_pre_co],
 y_pre_tr.mean(axis=1)).get("loss")
 
 v_solution = minimize(v_loss, [0, 0], method='L-BFGS-B')
 v_solution.x
 
 array([1.88034589, 0.00269853])

 有了最优 vs,就可以回到 find_w_given_vs 来获取考虑协变量的合成控制权重。不过需要注意的一点是,最终的解与不考虑协变量的解没有太大区别。这并不奇怪,因为 comp_download_pct 协变量的最优 v 是一个很小的数字,而且它并不比 app_download_pct 大很多:

 w_cov = find_w_given_vs(v_solution.x,
 [y_pre_co, x_pre_co],
 y_pre_tr.mean(axis=1)).get("w").round(3)
 w_cov
 
 array([-0. , -0. , 0. , -0. , -0. , -0. , 0.078, 0.001,
 0.033, 0. , -0. , 0.034, -0. , -0. , -0. , 0. ,
 0.016, 0.047, 0.03 , 0.01 , -0. , -0. , 0. , 0.055,
 -0. , 0. , -0. , 0. , 0. , 0. , -0. , 0.046,
 0.078, 0.007, 0. , 0. , 0.138, 0. , 0.022, 0.008,
 -0. , 0.201, 0. , 0.035, 0. , 0.161, -0. ])

有了这些权重,你可以对Y0进行预测,并获得考虑协变量的最终ATT数据:

 y0_hat = sum([x*v for x, v
 in zip([y_post_co, x_post_co], v_solution.x)]).dot(w_cov)
 att = y_post_tr.mean(axis=1) - y0_hat

下面的图显示了所得到的ATT,以及来自典型SC的ATT估计值,并且没有协变量。正如你所看到的,两者都非常相似:

加入协变量虽然不难,但需要一定的额外复杂度。出于这个原因,而且由于 Y_{pre,co} 往往足以预测 Y_{tr},我通常不会费心添加协变量。但也许你能找到非常有预测性的特征,从而证明添加协变量是合理的。

  • 26
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
贝叶斯因果推断是一种使用贝叶斯网络(Bayesian Network)进行因果关系推断的方法。贝叶斯网络是一种概率图模型,用于表示变量之间的依赖关系和因果关系。在贝叶斯网络中,节点表示变量,边表示变量之间的依赖关系。通过观察节点的状态,可以推断其他节点的状态。 在Python中,可以使用PyMC3库来构建贝叶斯网络模型。《Python贝叶斯分析》这本书从实际应用和编写程序的角度解释了贝叶斯统计的关键概念,并介绍了如何使用PyMC3来构建概率模型。这本书不要求读者具备生物学方面的基础知识,但需要读者具备使用Python编写程序的经验\[1\]。 贝叶斯因果推断的一个挑战是数据的结构与贝叶斯网络的独立性不一致。贝叶斯网络的推断算法旨在从概率中推断因果关系,与任何实验无关。因此,贝叶斯网络的推断是基于概率观察数据进行的。此外,贝叶斯网络的推断是从特定前提中得出一般性结论,与理论假设的表述无关。这是因为贝叶斯网络的推断是演绎的,而不是从因果假设的表述中得出的\[3\]。 因此,Python中的贝叶斯因果推断可以通过构建贝叶斯网络模型,并使用PyMC3库进行推断。这种方法可以帮助我们从观察数据中推断因果关系,并进行因果推断分析。 #### 引用[.reference_title] - *1* [Python贝叶斯分析 PDF 完整原版](https://blog.csdn.net/weixin_39850143/article/details/110996376)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [数学推导+纯Python实现机器学习算法12:贝叶斯网络](https://blog.csdn.net/weixin_37737254/article/details/102920363)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [贝叶斯因果网络_因果关系和贝叶斯网络](https://blog.csdn.net/weixin_26752765/article/details/108132740)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

打赏作者

水木流年追梦

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

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

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

打赏作者

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

抵扣说明:

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

余额充值