分享

causalinference: 使用Python做因果推断

 大邓的Python 2021-02-23

python虽然与R一样都可以做数据分析,但是在计量方面较为薄弱,python更像是干脏活,清洗数据用的。现在慢慢的python也有一些在计量的包,比如causalinference,这个包可以做因果推断分析。

安装

  1. !pip3 install causalinference

  1. Looking in indexes: https://pypi.tuna.tsinghua.edu.cn/simple

  2. Collecting causalinference

  3. Downloading https://pypi.tuna.tsinghua.edu.cn/packages/dc/7f/4504b42ef5a1158075954f54d08b95b2d5b2186da0ef9fcbcd0cf31411f2/CausalInference-0.1.3-py3-none-any.whl (51 kB)

  4. [K |████████████████████████████████| 51 kB 81 kB/s eta 0:00:0101

  5. [?25hInstalling collected packages: causalinference

  6. Successfully installed causalinference-0.1.3

数据导入

  1. import pandas as pd

  2. df = pd.read_csv('data.csv')

  3. df

数据描述

  • x1,x2,x3 协变量(控制变量)

  • y 因变量

  • istreatment 处置变量D,标注每条数据隶属于treatment或control组。1为treatment, 0为control。

  1. from causalinference import CausalModel

  2. Y = df['y'].values

  3. D = df['istreatment'].values

  4. X = df[['x1', 'x2', 'x3']].values

  5. #CausalModel参数依次为Y, D, X。其中Y为因变量

  6. causal = CausalModel(Y, D, X)

  7. causal

  1. <causalinference.causal.CausalModel at 0x13b9348d0>

描述性统计分析

  1. print(causal.summary_stats)

  1. Summary Statistics

  2. Controls (N_c=2509) Treated (N_t=2491)

  3. Variable Mean S.d. Mean S.d. Raw-diff

  4. --------------------------------------------------------------------------------

  5. Y -1.012 1.742 4.978 3.068 5.989

  6. Controls (N_c=2509) Treated (N_t=2491)

  7. Variable Mean S.d. Mean S.d. Nor-diff

  8. --------------------------------------------------------------------------------

  9. X0 -0.343 0.940 0.336 0.961 0.714

  10. X1 -0.347 0.936 0.345 0.958 0.730

  11. X2 -0.313 0.940 0.306 0.963 0.650

causal.summary_stats含有的指标字段名

  1. causal.summary_stats.keys()

  1. dict_keys(['N', 'K', 'N_c', 'N_t', 'Y_c_mean', 'Y_t_mean', 'Y_c_sd', 'Y_t_sd', 'rdiff', 'X_c_mean', 'X_t_mean', 'X_c_sd', 'X_t_sd', 'ndiff'])

使用OLS估计处置效应

估计处置效应最简单的方法是使用OLS方法,

CausalModel.est_via_ols(adj)

该方法有一个参数adj

  • adj=0 模型未使用X(协变量)

  • adj=1 模型使用了D(是否为处置组)和X(协变量)。

  • adj=2 模型使用了D(是否为处置组)、X(协变量)、D与X的交互

  • adj默认为2

  1. causal.est_via_ols(adj=2)

  2. print(causal.estimates)

  1. Treatment Effect Estimates: OLS

  2. Est. S.e. z P>|z| [95% Conf. int.]

  3. --------------------------------------------------------------------------------

  4. ATE 3.017 0.034 88.740 0.000 2.950 3.083

  5. ATC 2.031 0.040 51.183 0.000 1.953 2.108

  6. ATT 4.010 0.039 103.964 0.000 3.934 4.086

参数解读

  • ATE 平均处置效应(average treatment effect)

  • ATC 控制组的平均处置效应(average treatment effect for the controls)

  • ATT 处置组的平均处置效应(average treatment effect for the treated)

你们再试试adj设置为0和1分别运行出什么结果

倾向得分估计

我们估计处置效应时,很希望处置组和控制组很类似。比如研究受教育水平对个人收入的影响,其他变量如家庭背景、年龄、地区等协变量存在差异,我们希望控制组和处置组的之间的协变量平衡性尽可能的好,这样两个组就会很像,当对这两个组的受教育水平进行操作时,两个组的收入差异可以认为是受教育水平带来的。

让两个组很像,这里就用到倾向得分估计。

  1. causal.est_propensity_s()

  2. print(causal.propensity)

  1. Estimated Parameters of Propensity Score

  2. Coef. S.e. z P>|z| [95% Conf. int.]

  3. --------------------------------------------------------------------------------

  4. Intercept 0.005 0.035 0.145 0.885 -0.063 0.073

  5. X1 0.999 0.041 24.495 0.000 0.919 1.079

  6. X0 1.000 0.041 24.543 0.000 0.920 1.080

  7. X2 0.933 0.040 23.181 0.000 0.855 1.012

分层方法估计处置效应

倾向得分估计,让两个组尽量相似,但实际上这个相似值范围有点大。比如假设受教育水平对个人收入的影响,身高、体重等颜值信息(协变量)其实对收入也是有影响的,那么就应该对人群进行分层,不同颜值水平(分组)下受教育水平对个人收入的影响。

分层方法估计CausalModel.stratify_s() 自动选择协变量

  1. causal.stratify_s()

  2. print(causal.strata)

  1. Stratification Summary

  2. Propensity Score Sample Size Ave. Propensity Outcome

  3. Stratum Min. Max. Controls Treated Controls Treated Raw-diff

  4. --------------------------------------------------------------------------------

  5. 1 0.001 0.043 153 5 0.024 0.029 -0.049

  6. 2 0.043 0.069 148 8 0.056 0.059 0.142

  7. 3 0.070 0.118 283 29 0.093 0.092 0.953

  8. 4 0.119 0.178 268 45 0.147 0.147 1.154

  9. 5 0.178 0.240 247 65 0.208 0.210 1.728

  10. 6 0.240 0.361 451 174 0.299 0.300 2.093

  11. 7 0.361 0.427 196 117 0.393 0.395 2.406

  12. 8 0.427 0.499 153 159 0.465 0.464 2.868

  13. 9 0.499 0.532 82 75 0.515 0.515 2.973

  14. 10 0.532 0.568 65 91 0.551 0.553 3.259

  15. 11 0.568 0.630 114 198 0.600 0.601 3.456

  16. 12 0.630 0.758 180 445 0.693 0.696 3.918

  17. 13 0.758 0.818 77 236 0.787 0.789 4.503

  18. 14 0.818 0.876 57 255 0.845 0.849 4.937

  19. 15 0.876 0.933 23 289 0.904 0.904 5.171

  20. 16 0.933 0.998 12 300 0.957 0.963 6.822

更多详细信息可阅读代码中说明论文,可在项目中下载到的。

近期文章





Python网络爬虫与文本数据分析(视频课)

pandas 1.0最新版本特性抢先看

用python帮你生产指定内容的word文档

Modin:一行代码让pandas加速数十倍

2020年B站跨年晚会弹幕内容分析

综述:文本分析在市场营销研究中的应用

Lazy Prices公司年报内容变动碰上股价偷懒

使用pandas做数据可视化

用statsmodels库做计量分析

YelpDaset: 酒店管理类数据集10+G

NRC词语情绪词典和词语色彩词典

Loughran&McDonald金融文本情感分析库

股评师分析报告文本情感分析预测股价

使用分析师报告中含有的情感信息预测上市公司股价变动

【公开视频课】Python语法快速入门

【公开视频课】Python爬虫快速入门

一行pandas代码生成哑变量

使用Python读取图片中的文本数据

代码不到40行的超燃动态排序图

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多