Python 因果推断(下)

六、2007-2009 年大衰退期间加拿大就业市场上白人女性名字的溢价

原文:causal-methods.github.io/Book/6%29_The_Premium_of_Having_a_White_Female_Name_in_the_Canadian_Job_Market_During_the_Great_Recession_2007_2009.html

译者:飞龙

协议:CC BY-NC-SA 4.0

Vitor Kamada

电子邮件:[email protected]

最近更新:2020 年 9 月 15 日

我重新分析了 Oreopoulos(2011)的实验数据,并发现在 2007-2009 年大萧条期间,在加拿大的就业市场中,拥有白人女性名字是有优势的。白人女性在 2009 年 2 月至 9 月之间的回电率比白人男性高出 8%。考虑到白人男性在不同的回归规范下的回电率约为 10%,这一效应的幅度是相当高的。

Oreopoulos(2011)发现,英文名字的回电率为 15.7%,而印度、巴基斯坦、中国和希腊名字的回电率为 6%。我认为他的主要发现在很大程度上是由白人女性驱动的。我发现,在 2009 年 2 月至 9 月的大萧条最严重时期,拥有白人男性名字与印度、中国和希腊男性名字相比,并没有太多优势。

我使用了 Oreopoulos(2011)的数据集。每一行是发送给多个多伦多和蒙特利尔地区职业的简历。

import numpy as np
import pandas as pd
pd.set_option('precision', 3)

# Data from Oreopoulos (2011)
path = "https://github.com/causal-methods/Data/raw/master/" 
df = pd.read_stata(path + "oreopoulos.dta")
df.head(5) 
公司 ID 职业类型 name_ethnicity 额外证书 名字 语言技能 资格认证 参考 法律 列出的资格认证 说话技能 社交能力 写作能力 秋季数据 中国人 印度人 英国人 巴基斯坦人 中加人 相同经验
0 -3 行政 加拿大 0.0 JillWilson 0.0 0.0 0.0 0.0 0.0 70.0 50.0 67.0 2.0 NaN NaN NaN NaN NaN NaN
1 -3 行政 印度 0.0 PanavSingh 0.0 0.0 0.0 0.0 0.0 70.0 50.0 67.0 2.0 NaN NaN NaN NaN NaN NaN
2 -3 行政 印度 0.0 RahulKaur 0.0 0.0 0.0 1.0 1.0 70.0 50.0 67.0 2.0 NaN NaN NaN NaN NaN NaN
3 -3 行政 中国 0.0 雷丽 0.0 1.0 1.0 0.0 1.0 70.0 50.0 67.0 2.0 NaN NaN NaN NaN NaN NaN
4 -4 行政 印度 0.0 MayaKumar 1.0 0.0 0.0 0.0 0.0 80.0 70.0 65.0 2.0 NaN NaN NaN NaN NaN NaN

5 行×31 列

# Transform the variable of interest in % 
df["callback"] = 100*df["callback"] 

Oreopoulos(2011)收集的第一批实验数据是在 2008 年 4 月至 8 月之间。这是大萧条的“起始期”。

# Restrict data to April and August 2008
df0 = df[(df.fall_data == 0)] 

回电率对工作面试的比例对于加拿大名字(15.84%)要比中国和印度名字(9.23%和 9.53%)高得多。名族是随机的。不可能争辩说加拿大人有更多的教育或经验来证明大约 5%的差异。所有的简历在质量上都是一样的,除了申请人的名字。因此,我们可以得出结论,对移民的歧视是一个真实的现象。

mean = df0.groupby('name_ethnicity').agg([np.mean, np.size])
mean["callback"] 
平均值 大小
name_ethnicity
加拿大 15.845 953.0
中国 9.231 1430.0
印度 9.534 1416.0

在 2008 年 4 月至 8 月的样本中,女性名字似乎比男性名字稍微有一些优势,但可以忽略不计,以获得工作面试。这一结果支持了 Oreopoulos(2011)的发现。在他的论文中,女性的系数在大部分回归中都不具有统计学显著性。

prop = pd.crosstab(index= df0['name_ethnicity'], columns=df0['female'], 
            values=df0['callback'], aggfunc='mean')
prop 
女性 0.0 1.0
name_ethnicity
加拿大 15.551 16.122
中国 9.065 9.392
印度 9.490 9.577

Oreopoulos(2011)收集的第三波实验数据是在 2009 年 2 月至 9 月之间进行的。这是大萧条的最糟糕时期。

# Restrict data to February and September 2009
df2 = df[(df.fall_data == 2)] 

加拿大名字的回电率为 14%,而中国名字为 8.96%,英文名和中国姓氏为 7.13%,希腊为 10.11%,印度为 7.9%。

请注意,总体上,这第三波样本中的回电率略低于第一波样本,对于两个样本中的常见种族来说。

mean = df2.groupby('name_ethnicity').agg([np.mean, np.size])
mean["callback"] 
平均 大小
名字种族
加拿大 14.080 1044.0
中国 8.956 1418.0
中国-加拿大 7.128 491.0
希腊 10.109 366.0
印度 7.899 1937.0
import plotly.express as px

y = mean["callback"].values[:, 0]
x = mean["callback"].index

fig = px.bar(df2, x, y, color = x,
             title="Callback Rate for Interview by Name Ethnicity",
             labels={ "y": "Callback Rate (%)",
                      "x": "Name Ethnicity",                 
                      "color": ""} )

fig.update_layout(font_size = 17)
fig.show() 

在 2009 年 2 月至 9 月的样本中,白人女性的名字回电率为 18.3%,而白人男性的名字回电率为 10.17%。我们没有看到其丨他种族有这么大的差异。事实上,对于希腊名字来说,效果是相反的。希腊男性的名字回电率为 10.71%,而希腊女性的名字回电率为 9.6%。白人男性的名字比中国和印度男性的名字有优势,但幅度不像白人男性与白人女性之间的差异那么大。

prop = pd.crosstab(index= df2['name_ethnicity'], columns=df2['female'], 
            values=df2['callback'], aggfunc='mean')
prop 
女性 0.0 1.0
名字种族
加拿大 10.169 18.129
中国 8.715 9.177
中国-加拿大 6.410 7.782
希腊 10.714 9.596
印度 7.252 8.559
import plotly.graph_objects as go

ethnicity = prop.index
male = prop.values[:,0]
female = prop.values[:,1]

fig = go.Figure(data=[
         go.Bar(name='Male', x = ethnicity, y = male),
         go.Bar(name='Female', x = ethnicity, y = female) ])

fig.update_layout(barmode='group', font_size = 17,
      title = "Callback Rate for Interview by Gender",
      yaxis = dict(title='Callback Rate (%)'),
      xaxis = dict(title='Name Ethnicity') )

fig.show() 

有人可能会争辩说,有一些混杂因素导致了观察到的差异。例如,有人可能会说,在现实世界中,女性比男性更受教育和更合格。请记住,这是实验数据,所有简历都是人为构造的,所有相关维度都是由 Oreopoulos(2011)随机化的。控制变量表明,女性和男性彼此相似。

control = ['additional_credential', 'ba_quality',
           'extracurricular_skills', 'language_skills',
           'certificate', 'ma', 'same_exp', 'exp_highquality',
           'skillspeaking', 'skillsocialper', 'skillwriting']

df2.groupby('female').agg([np.mean])[control] 
附加证书 学士质量 课外技能 语言技能 证书 硕士 相同经验 经验高质量 说话技能 社交能力 写作技能
平均 平均 平均 平均 平均 平均 平均 平均 平均 平均 平均
女性
0.0 0.059 0.640 0.598 0.306 0.007 0.170 NaN 0.197 70.757 59.654 64.286
1.0 0.054 0.655 0.595 0.322 0.008 0.185 NaN 0.169 70.524 59.777 64.216

敏锐的读者可能会争辩说,仅仅表明男性和女性相互之间相似是不够的,以支持我关于白人女性溢价的论点。我必须表明样本中的平均白人女性与平均白人男性相似。对于某些变量,白人女性看起来略微更合格,但对于其丨他变量,略微不太合格。许多数据维度都是随机的,观察到的差异看起来是抽样变异的产物。总的来说,白人男性和女性看起来很相似。我们可以在回归框架中严格控制所有这些因素。我看到种族之间的变化比性别之间的变化更大。种族之间的变化看起来对实验来说过多。因此,我将按种族分解回归分析,并控制几个因素。

df2.groupby(['female', 'name_ethnicity']).agg([np.mean])[control] 
附加证书 学士质量 课外技能 语言技能 证书 硕士 相同经验 经验高质量 说话技能 社交能力 写作技能
平均 平均 平均 平均 平均 平均 平均 平均 平均 平均
女性 名字种族
0.0 加拿大 0.056 0.746 0.623 0.343 0.004 0.209 NaN 0.190 70.422 59.070 63.546
中国人 0.062 0.607 0.592 0.326 0.007 0.165 NaN 0.183 70.702 59.850 64.312
中-加 0.068 0.628 0.538 0.282 0.013 0.154 NaN 0.214 71.141 59.513 63.979
希腊人 0.065 0.774 0.631 0.321 0.012 0.214 NaN 0.232 70.976 59.696 65.220
印度人 0.055 0.586 0.596 0.276 0.006 0.147 NaN 0.200 70.846 59.862 64.582
1.0 加拿大 0.055 0.789 0.577 0.327 0.004 0.228 NaN 0.177 70.146 60.041 64.179
中国人 0.055 0.590 0.596 0.300 0.011 0.189 NaN 0.179 70.799 59.607 64.349
中-加 0.047 0.638 0.638 0.346 0.004 0.113 NaN 0.171 70.000 59.506 63.233
希腊人 0.045 0.808 0.566 0.308 0.010 0.217 NaN 0.136 71.258 60.662 64.894
印度人 0.055 0.608 0.599 0.334 0.008 0.172 NaN 0.163 70.503 59.657 64.257

y r j t y_{rjt} yrjt是一个虚拟变量,如果简历 r r r发送到工作 j j j在时间 t t t收到回电,则为 1;否则为 0。感兴趣的变量是“女性”虚拟变量和与“简历类型”的交互。

有五种“简历类型”:0) 英文名,加拿大教育和经验;1) 外国名字,加拿大教育和经验;2) 外国名字和教育,加拿大经验;3) 外国名字和教育,混合经验;和 4) 外国名字,教育和经验。

以下的线性概率模型是首选的规范:

y r j t = β F e m a l e r j t + γ R e s u m e   T y p e s r j t + δ F e m a l e r j t ⋅ R e s u m e   T y p e s r j t + α X + ϵ r j t y_{rjt}= \beta Female_{rjt}+\gamma Resume\ Types_{rjt}+ \delta Female_{rjt} \cdot Resume\ Types_{rjt} + \alpha X + \epsilon_{rjt} yrjt=βFemalerjt+γResume Typesrjt+δFemalerjtResume Typesrjt+αX+ϵrjt

其中 X X X是控制变量的向量, ϵ r j t \epsilon_{rjt} ϵrjt是通常的误差项。所有回归都呈现了对异方差性的稳健标准误差。

对于表 1、2 和 3,我们呈现了 4 个回归,以比较“加拿大人”与特定种族。逻辑是保持一个同质样本,避免可能混淆结果的种族变化。

表 1 呈现了没有交互作用和控制变量的结果。作为女性的优势范围从增加 3.64%到 5.97%的回电率,相对于男性。白人男性的回电率,基准(类型 0),范围从 11.14%到 12.29%。Oreopoulos(2011)提出的类型 0 的估计值从 15.4%到 16%不等,但他的估计捕捉了英文名字的影响,而没有孤立地考虑性别影响。

我们看到一个模式,类型 1、2、3 和 4 的系数都是负数,并且随着“外国”的程度绝对值增加。一个人在名字、教育和经验方面越“外国”,回电率就越低。但仅仅一个外国名字就足以使回电率比英文名字低 3.38%到 5.11%。总体而言,结果在 1%的显著水平上是统计学显著的。一个例外是类型 1 的系数,用于英文名和中国姓氏的回归(3)。这里描述的模式与 Oreopoulos(2011)报告的主要发现相匹配。

import statsmodels.formula.api as smf

# Sample Restriction based on name ethnicity
Canada = df2.name_ethnicity == "Canada"
Indian = df2[(Canada) | (df2.name_ethnicity == "Indian")]
Chinese = df2[(Canada) | (df2.name_ethnicity == "Chinese")]
Chn_Cdn = df2[(Canada) | (df2.name_ethnicity == "Chn-Cdn")]
Greek = df2[(Canada) | (df2.name_ethnicity == "Greek")]

sample = [Indian, Chinese, Chn_Cdn, Greek]

#  Run the simple model for each ethnicity
# and save the results
model1 = "callback ~ female + C(type)"

result1 = []
for data in sample:
   ols = smf.ols(model1, data).fit(cov_type='HC1')
   result1.append(ols) 
C:\Anaconda\envs\textbook\lib\site-packages\statsmodels\tools\_testing.py:19: FutureWarning:

pandas.util.testing is deprecated. Use the functions in the public API at pandas.testing instead. 
#  Library to print professional publication
# tables in Latex, HTML, etc.
!pip install stargazer 
Requirement already satisfied: stargazer in c:\anaconda\envs\textbook\lib\site-packages (0.0.5) 
WARNING: Error parsing requirements for numpy: [Errno 2] No such file or directory: 'c:\\anaconda\\envs\\textbook\\lib\\site-packages\\numpy-1.19.2.dist-info\\METADATA' 
# Settings for a nice table
from stargazer.stargazer import Stargazer
stargazer = Stargazer(result1)

stargazer.title('Table 1 - Callback Rates by Resume Type')

names = ['Indian', 'Chinese', 'Chn_Cdn', 'Greek']
stargazer.custom_columns(names, [1, 1, 1, 1])

order = ['female', 'Intercept', 'C(type)[T.1.0]',
         'C(type)[T.2.0]', 'C(type)[T.3.0]',
         'C(type)[T.4.0]']     
stargazer.covariate_order(order)

dict1 = {'C(type)[T.1.0]': '1) Foreign Name, Cdn Educ and Exp',
         'C(type)[T.2.0]': '2) Foreign Name and Educ, Cdn exp',
         'C(type)[T.3.0]': '3) Foreign Name and Educ, Mixed Exp',
         'C(type)[T.4.0]': '4) All Foreign (Name, Educ, and Exp)',
              'Intercept': '0) English Name, Cdn Educ and Exp',
                 'female': 'Female'}
stargazer.rename_covariates(dict1)

stargazer 

表 1 - 简历类型的回电率

女性
0) 英文名,加拿大教育和经验
1) 外国名字,加拿大教育和经验
2) 外国名字和教育,加拿大经验
3) 外国名字和教育,混合经验
4) 所有外国人(姓名,教育和经验)
观察
调整后的 R²
残差标准误差
F 统计量
注:

表 2 添加了女性和简历类型的交互项。女性的系数仅捕捉了白人女性的影响,因为外国女性是由女性和类型之间的交互项捕捉的。与白人男性(10.17%的基线)相比,白人女性的回访率增加了 7.96%。

交互项的系数在绝对值上为负,但并非全部统计上显着。这种模式表明,外国女性的回访率与白人女性相比非常低。

有趣的是,类型 1、2、3 和 4 的系数在幅度上较低,并且与表 1 相比在统计上不太显着。这种模式表明,白人男性比印度人和中国姓氏的人有优势,但不包括希腊人或中国人(名字和姓氏)。这两个最后一组的系数在统计上不显着。

model2 = "callback ~ female*C(type)"

result2 = []
for data in sample:
   ols = smf.ols(model2, data).fit(cov_type='HC1')
   result2.append(ols) 
stargazer = Stargazer(result2)

stargazer.title('Table 2 - Callback Rates by Resume Type and Gender')

stargazer.custom_columns(names, [1, 1, 1, 1])

dict2 = {'female:C(type)[T.1.0]':'[Female]x[1]',
         'female:C(type)[T.2.0]':'[Female]x[2]',
         'female:C(type)[T.3.0]':'[Female]x[3]',
         'female:C(type)[T.4.0]':'[Female]x[4]'}

list2 = list(dict2.keys())

dict2.update(dict1)
stargazer.rename_covariates(dict2)

list2 = order + list2
stargazer.covariate_order(list2)

stargazer 

表 2 - 简历类型和性别的回访率

女性
0) 英文名,加拿大教育和经验
1) 外国名字,加拿大教育和经验
2) 外国名字和教育,加拿大经验
3) 外国名字和教育,混合经验
4) 所有外国人(姓名,教育和经验)
[女性]x[1]
[女性]x[2]
[女性]x[3]
[女性]x[4]
观察
调整后的 R²
残差标准误差
F 统计量
注:

表 3 添加了控制变量作为鲁棒性检查。总体结果与表 2 相似。与表 2 相比,白人女性的影响甚至略有增加。白人女性的巨大溢价仍然超过所有其丨他类别。白人女性的溢价优于来自世界排名前 200 的大学的学士学位,大型公司的经验,课外活动,流利的法语和其丨他语言以及加拿大硕士学位的累积影响。

请注意,对于类型 1,只有印度回归的系数在统计上显着。白人男性的名字与中国,中国加拿大和希腊名字没有优势。

control1 = "+ ba_quality + extracurricular_skills + language_skills"
control2 = "+ ma + exp_highquality"
model3 = "callback ~ female*C(type)" + control1 + control2

result3 = []
for data in sample:
   ols = smf.ols(model3, data).fit(cov_type='HC1')
   result3.append(ols) 
stargazer = Stargazer(result3)

stargazer.title('Table 3 - Callback Rates and Robustness Checks')

stargazer.custom_columns(names, [1, 1, 1, 1])

dict3 = {'ba_quality':'Top 200 world ranking university',
         'exp_highquality':'High quality work experience',
         'extracurricular_skills'	:'List extra-curricular activities',
         'language_skills':'Fluent in French and other languages',
         'ma':'Canadian master’s degree'}

list3 = list(dict3.keys())

dict3.update(dict2)
stargazer.rename_covariates(dict3)

list3 = list2 + list3
stargazer.covariate_order(list3)

stargazer 

表 3 - 回访率和鲁棒性检查

女性
0) 英文名字,加拿大教育和经验
1) 外国名字,加拿大教育和经验
2) 外国名字和教育,加拿大经验
3) 外国名字和教育,混合经验
4) 所有外国人(姓名,教育和经验)
[女性]x[1]
[女性]x[2]
[女性]x[3]
[女性]x[4]
世界排名前 200 的大学
高质量的工作经验
列出课外活动
流利的法语和其丨他语言
加拿大硕士学位
观察
调整后的 R²
残差标准误差
F 统计量
注:

练习

1)为什么白人女性的溢价出现在 2009 年 2 月至 9 月的大衰退期间,而在 2008 年 4 月和 8 月之前没有出现?推测。

2)招聘人员可能更愿意与白人女性丨交谈,但不一定会雇佣她们。我如何能确定更高的回电率是否反映在更多的工作提供中。例如,我如何获取数据来检查这种关系?

3)你能从下表推断出什么?你有什么见解要分享吗?

pd.crosstab(index= [df2['name_ethnicity'], df2['female'],
                           df2['name']], columns=df2['type'], 
                         values=df2['callback'], aggfunc='mean') 
类型 0.0 1.0 2.0 3.0 4.0
名字 _ 种族 女性 名字
加拿大 0.0 格雷格·约翰逊 11.561 NaN NaN NaN NaN
约翰·马丁 8.235 NaN NaN NaN NaN
马修·威尔逊 10.638 NaN NaN NaN NaN
1.0 艾莉森·约翰逊 18.675 NaN NaN NaN NaN
凯丽·马丁 20.455 NaN NaN NaN NaN
吉尔·威尔逊 15.205 NaN NaN NaN NaN
中国人 0.0 刘东 NaN 10.870 3.390 13.158 2.381
李蕾 NaN 14.062 9.756 8.065 11.364
张勇 NaN 10.227 7.407 3.509 8.333
1.0 刘敏 NaN 8.235 5.357 11.321 15.556
李娜 NaN 10.127 12.698 5.556 2.703
张秀英 NaN 11.927 6.780 9.091 7.018
中国-加拿大 0.0 王艾瑞克 NaN 9.677 3.390 8.889 0.000
1.0 王美琪 NaN 12.500 6.780 4.348 3.571
希腊 0.0 鲁卡斯·米诺普洛斯 NaN 10.714 NaN NaN NaN
1.0 NicoleMinsopoulos NaN 9.596 NaN NaN NaN
印度人 0.0 阿尔琼·库马尔 NaN 8.642 8.333 3.125 4.762
帕纳夫·辛格 NaN 1.333 15.942 7.317 2.500
拉胡尔·考尔 NaN 8.571 10.769 5.455 7.317
萨米尔·夏尔马 NaN 5.814 6.897 10.256 6.522
1.0 MayaKumar NaN 14.286 6.944 3.448 5.263
PriyankaKaur NaN 6.481 14.815 3.636 5.128
ShreyaSharma NaN 13.158 8.772 4.651 5.128
TaraSingh NaN 14.286 8.065 9.091 4.444

4)你能从下表推断出什么?你有什么见解要分享吗?

pd.crosstab(index= df2['occupation_type'],
                   columns=[df2['name_ethnicity'], df2['female']], 
                   values=df2['callback'], aggfunc='mean') 
姓名种族 加拿大 中国 中国-加拿大 希腊 印度
女性 0.0 1.0 0.0 1.0 0.0
职业类型
会计 2.703 8.929 5.769 6.780 0.000
行政 7.895 23.288 10.112 8.036 6.897
土木工程师 5.556 50.000 6.250 6.250 0.000
文书工作 4.444 8.140 5.172 6.000 0.000
电子商务 0.000 0.000 9.091 0.000 0.000
电气工程师 6.250 28.571 7.143 8.333 14.286
行政助丨理 23.077 17.647 5.263 16.000 16.667
金融 16.667 26.316 5.000 12.195 0.000
餐饮服务经理 16.667 16.667 0.000 8.333 20.000
人力资源工资 20.000 18.182 0.000 0.000 0.000
保险 53.846 40.000 14.286 13.636 28.571
市场营销和销丨售 12.791 22.222 12.409 11.966 9.091
生产 0.000 0.000 0.000 4.762 0.000
程序员 10.256 17.391 13.462 10.526 0.000
零售 19.048 21.622 14.545 17.647 22.727
技术 0.000 16.667 3.226 4.000 0.000

5)解释表 4 的结果。重点关注固定效应(职业,姓名和城市)的添加。

FE = "+ C(occupation_type) + C(city) + C(name)"
model4 = "callback ~ female*C(type) " + control1 + control2 + FE

result4 = []
for data in sample:
   ols = smf.ols(model4, data).fit(cov_type='HC1')
   result4.append(ols) 
stargazer = Stargazer(result4)

stargazer.title('Table 4 - Callback Rates and Fixed Effects')
stargazer.custom_columns(names, [1, 1, 1, 1])
stargazer.rename_covariates(dict3)
stargazer.covariate_order(list3)

stargazer.add_line('Fixed Effects', ['', '', '', ''])
stargazer.add_line('Occupation', ['Yes', 'Yes', 'Yes', 'Yes'])
stargazer.add_line('Name', ['Yes', 'Yes', 'Yes', 'Yes'])
stargazer.add_line('City', ['Yes', 'Yes', 'Yes', 'Yes'])

stargazer 
C:\Anaconda\envs\textbook\lib\site-packages\statsmodels\base\model.py:1752: ValueWarning:

covariance of constraints does not have full rank. The number of constraints is 43, but rank is 1

C:\Anaconda\envs\textbook\lib\site-packages\statsmodels\base\model.py:1752: ValueWarning:

covariance of constraints does not have full rank. The number of constraints is 41, but rank is 39

C:\Anaconda\envs\textbook\lib\site-packages\statsmodels\base\model.py:1752: ValueWarning:

covariance of constraints does not have full rank. The number of constraints is 37, but rank is 35

C:\Anaconda\envs\textbook\lib\site-packages\statsmodels\base\model.py:1752: ValueWarning:

covariance of constraints does not have full rank. The number of constraints is 31, but rank is 29 

表 4 - 回拨率和固定效应

印度
女性
0) 英文姓名,加拿大教育和经验
1) 外国姓名,加拿大教育和经验
2) 外国姓名和教育,加拿大经验
3) 外国姓名和教育,混合经验
4) 所有外国(姓名,教育和经验)
[女性]x[1]
[女性]x[2]
[女性]x[3]
[女性]x[4]
世界排名前 200 的大学
高质量工作经验
列出课外活动
流利的法语和其丨他语言
加拿大硕士学位
固定效应
职业
名字
城市
观察
调整后的 R²
残差标准误差
F 统计量
注:

6)Oreopoulos (2011)收集的第二波实验数据是在 2008 年 9 月至 11 月之间。使用这些数据来调查在加拿大就业市场中是否拥有白人女性姓名会有额外的优势。只生成一张专业出版表,并解释主要结果。

7)对于这个问题,要像 Bertrand & Mullainathan (2004)和 Oreopoulos (2011)一样打破常规思维。一些研究认为身高较高的人赚更多钱并不是因为身高的直接影响,而是通过自尊心的间接影响。提出一个可行的研究设计来测丨试以下因果关系:

a) 身高和薪水。

b) 身高和自尊心。

c) 自尊心和薪水。

参考

Bertrand, Marianne, and Sendhil Mullainathan. (2004). Are Emily and Greg More Employable Than Lakisha and Jamal? A Field Experiment on Labor Market Discrimination. American Economic Review, 94 (4): 991-1013.

Oreopoulos, Philip. (2011). Why Do Skilled Immigrants Struggle in the Labor Market? A Field Experiment with Thirteen Thousand Resumes. American Economic Journal: Economic Policy, 3 (4): 148-71.

七、卖丨淫合法化对犯罪的影响

原文:causal-methods.github.io/Book/7%29_The_Impact_of_Legalizing_Prostitution_on_Crime.html

译者:飞龙

协议:CC BY-NC-SA 4.0

Vitor Kamada

电子邮件:[email protected]

最近更新:2020 年 11 月 2 日

在荷兰,有法定的卖丨淫区,荷兰称之为 tippelzones。Bisschop 等人(2017)报告称,tippelzone 的开放可以减少大约 30-40%的性丨虐丨待和强丨奸案件。

让我们打开 Bisschop 等人的数据集。每一行是荷兰的一个城市。同一个城市在 1994 年至 2011 年之间被观察到。

import numpy as np
import pandas as pd
pd.set_option('precision', 3)

# Data from Bisschop et al. (2017)
path = "https://github.com/causal-methods/Data/raw/master/" 
df = pd.read_stata(path + "CBSregist2015.dta")
df.head(5) 
城市 年份 开放 关闭 城市 1 logpopdens openingReg mayorCDA mayorCU mayorD66 相似盗窃率 聚合盗窃率 相似盗窃率的自然对数 聚合盗窃率的自然对数 盗窃率 盗窃率的自然对数 职务侵犯率 职务暴力率 职务侵犯率的自然对数 职务暴力率的自然对数
0 阿姆斯特丹 1994-01-01 0.0 0.0 1.0 8.381 0.0 0.0 0.0 0.0 59.246 57.934 8.364 8.342 117.181 9.046 7.596 5.110 6.310 5.914
1 阿姆斯特丹 1995-01-01 0.0 0.0 1.0 8.379 0.0 0.0 0.0 0.0 50.815 43.823 8.208 8.060 94.637 8.830 7.061 4.361 6.234 5.753
2 阿姆斯特丹 1996-01-01 1.0 0.0 1.0 8.373 0.0 0.0 0.0 0.0 42.333 37.111 8.020 7.888 79.444 8.649 7.520 5.431 6.292 5.966
3 阿姆斯特丹 1997-01-01 1.0 0.0 1.0 8.369 0.0 0.0 0.0 0.0 46.843 32.860 8.117 7.762 79.704 8.648 6.852 4.195 6.194 5.704
4 阿姆斯特丹 1998-01-01 1.0 0.0 1.0 8.373 0.0 0.0 0.0 0.0 45.255 33.907 8.086 7.798 79.162 8.646 6.127 4.595 6.087 5.799

5 行×65 列

让我们将城市分成 3 组。大城市和中等城市至少在某一年有 tippelzone,而样本中的其丨他城市没有 tippelzone。

big_cities = ["Amsterdam", "Rotterdam", "Den Haag"]
medium_cities = ["Utrecht", "Nijmegen", "Groningen",
                 "Heerlen", "Eindhoven", "Arnhem"]

# Classify cities
def classify(var):
    if var in big_cities:
        return "Big Cities"
    elif var in medium_cities:
        return "Medium Cities"    
    else:   
        return "No tippelzone"

df['group'] = df["city"].apply(classify) 

以下是每 10,000 名居民的年度犯罪报告。总体而言,大城市的犯罪率更高。唯一的例外是与毒丨品有关的犯罪。

outcome = ['sexassaultpcN', 'rapepcN', 
	'drugspcN', 'maltreatpcN', 'weaponspcN']

df.groupby('group')[outcome].mean().T 
大城市 中等城市 无 tippelzone
性丨侵犯率 0.775 0.626 0.664
强丨奸率 1.032 0.846 0.691
毒丨品犯罪率 14.921 15.599 12.779
maltreatpcN 21.259 18.665 17.864
weaponspcN 5.635 4.385 4.207

tippelzones 城市的人口和人口密度比没有 tippelzones 的城市更多。平均家庭收入(以 1,000 欧元计)在 3 个组中相似。tippelzones 城市也有受过较高教育的个体。移民比例在大城市中更高(11.4%)。社丨会保险福利(“insurWWAO_pc”)的份额与 3 个组相似。

demographics = ['popul_100', 'pop_dens_100', 'popmale1565_100',
            'inkhh', 'educhpc', 'nondutchpc', 'insurWWAO_pc']

df.groupby('group')[demographics].mean().T 
大城市 中等城市 无 tippelzone
popul_100 5974.886 1724.191 1131.138
pop_dens_100 43.258 22.977 19.560
popmale1565_100 2101.446 617.019 392.255
inkhh 29.052 28.989 30.502
educhpc 0.300 0.317 0.245
非荷兰人比例 0.114 0.059 0.052
insurWWAO_pc 0.074 0.081 0.078

基丨督丨教联盟在没有 tippelzone 的城市中拥有更多的市长(31%)。值得一提的是,该党反对开放 tippelzone。

political_party = ['mayorSoc', 'mayorLib', 'mayorChr']
df.groupby('group')[political_party].mean().T 
大城市 中等城市 无 tippelzone
mayorSoc 0.481 0.556 0.410
mayorLib 0.259 0.324 0.278
mayorChr 0.259 0.120 0.312

数据集是平衡的面板数据。有必要按顺序声明指数:分析单位和时间单位。

df['year'] = pd.DatetimeIndex(df['year']).year
df['Dyear'] = pd.Categorical(df.year)

# Set Panel Data
# Set city as the unit of analysis
df25 = df.set_index(['city1', 'year']) 

Y c t Y_{ct} Yct为城市 c c c在年份 t t t的犯罪率。设 D c t D_{ct} Dct = 1,如果城市 c c c在年份 t t t有开放的 tippelzone;否则为 0。让我们估计以下模型:

l n ( Y c t ) = α c + ρ D c t + β X c t + γ t + ϵ c t ln(Y_{ct})=\alpha_c+\rho D_{ct}+\beta X_{ct}+\gamma_t + \epsilon_{ct} ln(Yct)=αc+ρDct+βXct+γt+ϵct

其中 α c \alpha_c αc是城市固定效应, X c t X_{ct} Xct是控制变量向量, γ t \gamma_t γt是年固定效应, ϵ c t \epsilon_{ct} ϵct是通常的误差项。

import statsmodels.formula.api as smf

Ys = ["lnsexassaultN", "lnrapeN", "lndrugsN",
      "lnweaponsN", "lnmaltreatN"]

base = "~ 1 + opening"
fe = "+ C(city) + C(Dyear)"

controls = ['logpopmale1565', 'logpopdens', 'inkhh', 
	'educhpc', 'nondutchpc', 'insurWWAO', 'mayorCDA',
  'mayorCU', 'mayorD66', 'mayorVVD']

Xs = ""
for var in controls:
    Xs = Xs + '+' + var

columns = []
for Y in Ys:
  result = smf.ols(Y + base + fe + Xs, df25).fit(cov_type='cluster',
                cov_kwds={'groups': df25['city']})
  columns.append(result) 
C:\Anaconda\envs\textbook\lib\site-packages\statsmodels\tools\_testing.py:19: FutureWarning: pandas.util.testing is deprecated. Use the functions in the public API at pandas.testing instead.
  import pandas.util.testing as tm 
#  Library to print professional publication
# tables in Latex, HTML, etc.
!pip install stargazer 
Requirement already satisfied: stargazer in c:\anaconda\envs\textbook\lib\site-packages (0.0.5) 
WARNING: Error parsing requirements for numpy: [Errno 2] No such file or directory: 'c:\\anaconda\\envs\\textbook\\lib\\site-packages\\numpy-1.19.2.dist-info\\METADATA' 

第 1 列表明开放 tippelzone 将性丨虐丨待减少 26%( e − 0.302 − 1 e^{-0.302}-1 e0.3021)。在其丨他列中,tippelzone 的系数在统计上不显著。看起来合法化卖丨淫会减少性丨虐丨待,但不会减少其丨他犯罪,如强丨奸、攻击、非法武器和毒丨品相关犯罪。

# Settings for a nice table
from stargazer.stargazer import Stargazer
stargazer = Stargazer(columns)

stargazer.title('The Impact of Tippelzone on Crime')

names = ['Sex Abuse', 'Rape', 'Drugs', 'Weapons', 'Assault']
stargazer.custom_columns(names, [1, 1, 1, 1, 1])

stargazer.covariate_order(['opening'])

stargazer.add_line('Covariates', ['Yes', 'Yes', 'Yes', 'Yes', 'Yes'])

stargazer.add_line('City Fixed Effects', ['Yes', 'Yes', 'Yes', 'Yes', 'Yes'])
stargazer.add_line('Year Fixed Effects', ['Yes', 'Yes', 'Yes', 'Yes', 'Yes'])

stargazer 
C:\Anaconda\envs\textbook\lib\site-packages\statsmodels\base\model.py:1752: ValueWarning: covariance of constraints does not have full rank. The number of constraints is 52, but rank is 24
  'rank is %d' % (J, J_), ValueWarning)
C:\Anaconda\envs\textbook\lib\site-packages\statsmodels\base\model.py:1752: ValueWarning: covariance of constraints does not have full rank. The number of constraints is 52, but rank is 24
  'rank is %d' % (J, J_), ValueWarning)
C:\Anaconda\envs\textbook\lib\site-packages\statsmodels\base\model.py:1752: ValueWarning: covariance of constraints does not have full rank. The number of constraints is 52, but rank is 24
  'rank is %d' % (J, J_), ValueWarning)
C:\Anaconda\envs\textbook\lib\site-packages\statsmodels\base\model.py:1752: ValueWarning: covariance of constraints does not have full rank. The number of constraints is 52, but rank is 24
  'rank is %d' % (J, J_), ValueWarning)
C:\Anaconda\envs\textbook\lib\site-packages\statsmodels\base\model.py:1752: ValueWarning: covariance of constraints does not have full rank. The number of constraints is 52, but rank is 24
  'rank is %d' % (J, J_), ValueWarning) 

Tippelzone 对犯罪的影响

开放
协变量
城市固定效应
年固定效应
观察
调整 R²
残差标准误差
F 统计量
注意:
import math
math.exp(-0.302) - 1 
-0.2606619351104681 

练习

1)在论文的引言部分,Bisschop 等人(2017: 29)表示:“我们的研究是第一个提供卖丨淫监丨管与犯罪之间关联的因果证据之一。”在讨论部分,Bisschop 等人(2017:44)表示:“开放 tippelzone,无论是否有许可制度,都与性丨虐丨待和强丨奸的短期减少 30-40%相关,并且结果在不同规范下都是稳健的。”为什么 Bisschop 等人(2017)在引言部分使用“因果”一词,在讨论部分使用“相关”一词?您是否认为 Bisschop 等人(2017)的主要结果是“因果”还是“相关”?请解释。

2)Bisschop 等人(2017: 29)表示:“我们进行了几项实证测丨试,以评估 tippelzone 开放周围的内生犯罪趋势。”他们为什么这样做?这其中的逻辑是什么?是否存在内生犯罪趋势?请解释并具体说明您的答案。

3)Bisschop 等人(2017: 36)表示:“…时间趋势 μ t \mu_t μt是使用年固定效应来建模的。”模拟时间趋势的其丨他方法是什么?编写不同假设下创建时间趋势的代码片段。提示:记住这是面板数据。在横截面数据中有效的代码将在面板数据结构中创建错误的变量。

4)Bisschop 等人(2017: 36)表示:“我们使用差异中的差异规范来研究 tippelzone 存在对各种犯罪的影响。”部署差异中的差异估计器的关键假设是什么?

5)复制表格“Tippelzone 对犯罪的影响”,不包括阿姆斯特丹、鹿特丹和海牙。此外,用以下四个变量替换变量“opening”:

i) “everopenNoReg”: 如果城市 c c c在年份 t t t之前曾开放过没有许可证的 tippelzone,则为 1,否则为 0。

ii) “openingRegP”: 如果城市 c c c在年份 t t t之前开放了 tippelzone 并引入了事后许可证,则为 1,否则为 0。

iii) “openingRegA”: 如果城市 c c c在年份 t t t之前曾开放过带有许可证的 tippelzone,则为 1,否则为 0。

iv) “closing”: 如果城市 c c c在年份 t t t之前关闭 tippelzone,则为 1,否则为 0。

解释结果。

参考

Bisschop, Paul, Stephen Kastoryano, and Bas van der Klaauw. (2017). 街头卖丨淫区和犯罪. 美丨国经济学杂志:经济政策,9 (4): 28-63.

八、Airbnb 的主人是否歧视黑人客人?

原文:causal-methods.github.io/Book/8%29_Do_Hosts_Discriminate_against_Black_Guests_in_Airbnb.html

译者:飞龙

协议:CC BY-NC-SA 4.0

Vitor Kamada

电子邮件:[email protected]

最后更新时间:11-1-2020

Edelman et al.(2017)发现,黑人名字听起来比白人名字听起来更不可能被 Airbnb 接受为客人,减少了 16%。这个结果不仅仅是相关性。种族变量是随机的。黑人和白人之间唯一的区别是名字。除此之外,黑人和白人客人是一样的。

让我们打开 Edelman 等人(2017)的数据集。每一行是 2015 年 7 月 Airbnb 的一处物业。样本由巴尔的摩、达拉斯、洛杉矶、圣路丨易斯和华丨盛丨顿特区的所有物业组成。

import numpy as np
import pandas as pd
pd.set_option('precision', 3)

# Data from Edelman et al. (2017)
path = "https://github.com/causal-methods/Data/raw/master/" 
df = pd.read_csv(path + "Airbnb.csv")
df.head(5) 
主人回应 回应日期 消息数量 自动编码 纬度 经度 床类型 物业类型 取消政策 客人数量 洛杉矶 圣路丨易斯 华丨盛丨顿特区 总客人 原始黑人 物业黑人 任何黑人 过去客人合并 九月填充 pr 填充
0 2015-07-19 08:26:17 2.0 1.0 34.081 -118.270 真正的床 房子 灵活 3.0 1 0 0 11.0 0.0 0.0 0.0 匹配(3) 1 0.412
1 否或不可用 2015-07-14 14:13:39 NaN 1.0 38.911 -77.020 NaN 房子 中等 2.0 0 0 1 167.0 0.0 0.0 0.0 匹配(3) 1 0.686
2 请求更多信息(你能验证吗?有多少… 2015-07-20 16:24:08 2.0 0.0 34.005 -118.481 拉出沙发 公寓 严格 1.0 1 0 0 19.0 0.0 0.0 0.0 匹配(3) 0 0.331
3 我会回复你 2015-07-20 06:47:38 NaN 0.0 34.092 -118.282 NaN 房子 严格 8.0 1 0 0 41.0 0.0 0.0 0.0 匹配(3) 0 0.536
4 未发送消息 . NaN 1.0 38.830 -76.897 真正的床 房子 严格 2.0 0 0 1 28.0 0.0 0.0 0.0 匹配(3) 1 0.555

5 行×104 列

下面的图表显示,黑人客人收到的“是”的回应比白人客人少。有人可能会争辩说 Edelman 等人(2017)的结果是由主人回应的差异驱动的,比如有条件的或非回应。例如,你可以争辩说黑人更有可能有被归类为垃丨圾邮件的假账户。然而,请注意,歧视结果是由“是”和“否”驱动的,而不是由中间回应驱动的。

# Data for bar chart
count = pd.crosstab(df["graph_bins"], df["guest_black"])

import plotly.graph_objects as go

node = ['Conditional No', 'Conditional Yes', 'No',
        'No Response', 'Yes']
fig = go.Figure(data=[
    go.Bar(name='Guest is white', x=node, y=count[0]),
    go.Bar(name='Guest is African American', x=node, y=count[1]) ])

fig.update_layout(barmode='group',
  title_text = 'Host Responses by Race',
  font=dict(size=18) )

fig.show() 

让我们复制 Edelman 等人(2017)的主要结果。

import statsmodels.api as sm

df['const'] = 1 

# Column 1
#  The default missing ='drop' of statsmodels doesn't apply
# to the cluster variable. Therefore, it is necessary to drop
# the missing values like below to get the clustered standard 
# errors.
df1 = df.dropna(subset=['yes', 'guest_black', 'name_by_city'])
reg1 = sm.OLS(df1['yes'], df1[['const', 'guest_black']])
res1 = reg1.fit(cov_type='cluster',
                cov_kwds={'groups': df1['name_by_city']})

# Column 2
vars2 = ['yes', 'guest_black', 'name_by_city', 
        'host_race_black', 'host_gender_M']
df2 = df.dropna(subset = vars2)
reg2 = sm.OLS(df2['yes'], df2[['const', 'guest_black',
                    'host_race_black', 'host_gender_M']])
res2 = reg2.fit(cov_type='cluster',
                cov_kwds={'groups': df2['name_by_city']})

# Column 3
vars3 = ['yes', 'guest_black', 'name_by_city', 
         'host_race_black', 'host_gender_M',
         'multiple_listings', 'shared_property',
         'ten_reviews', 'log_price']
df3 = df.dropna(subset = vars3)
reg3 = sm.OLS(df3['yes'], df3[['const', 'guest_black',
                    'host_race_black', 'host_gender_M',
                    'multiple_listings', 'shared_property',
                    'ten_reviews', 'log_price']])
res3 = reg3.fit(cov_type='cluster',
                cov_kwds={'groups': df3['name_by_city']})

columns =[res1, res2, res3] 
C:\Anaconda\envs\textbook\lib\site-packages\statsmodels\tools\_testing.py:19: FutureWarning:

pandas.util.testing is deprecated. Use the functions in the public API at pandas.testing instead. 
#  Library to print professional publication
# tables in Latex, HTML, etc.
!pip install stargazer 
Requirement already satisfied: stargazer in c:\anaconda\envs\textbook\lib\site-packages (0.0.5) 
WARNING: Error parsing requirements for numpy: [Errno 2] No such file or directory: 'c:\\anaconda\\envs\\textbook\\lib\\site-packages\\numpy-1.19.2.dist-info\\METADATA' 

在第一列中,听起来像白人的名字被接受的概率为 49%;而听起来像黑人的名字被接受的概率大约为 41%。因此,黑人名字带来了 8%的惩罚。这个结果在第 2 列和第 3 列的一组控制变量中非常稳健。

# Settings for a nice table
from stargazer.stargazer import Stargazer
stargazer = Stargazer(columns)
stargazer.title('The Impact of Race on Likelihood of Acceptance')
stargazer 

种族对接受可能性的影响

常数
黑人客人
主人性别 M
主人种族黑人
对数价丨格
多个列表
共享物业
十次评论
观察
调整后的 R²
残差标准误差
F 统计量
注:

下表显示了有关主人和房产的摘要统计信息。在实验中,控制变量的平均值与分组实验和对照组的平均值相同。

control = ['host_race_white', 'host_race_black', 'host_gender_F', 
	'host_gender_M', 'price', 'bedrooms', 'bathrooms', 'number_of_reviews', 
	'multiple_listings', 'any_black', 'tract_listings', 'black_proportion']

df.describe()[control].T 
计数 平均值 标准差 最小值 25% 50% 75% 最大值
host_race_white 6392.0 0.634 0.482 0.0 0.00 1.00 1.000 1.000
host_race_black 6392.0 0.078 0.269 0.0 0.00 0.00 0.000 1.000
host_gender_F 6392.0 0.376 0.485 0.0 0.00 0.00 1.000 1.000
host_gender_M 6392.0 0.298 0.457 0.0 0.00 0.00 1.000 1.000
价丨格 6302.0 181.108 1280.228 10.0 75.00 109.00 175.000 100000.000
卧室 6242.0 3.177 2.265 1.0 2.00 2.00 4.000 16.000
浴室 6285.0 3.169 2.264 1.0 2.00 2.00 4.000 16.000
评论数量 6390.0 30.869 72.505 0.0 2.00 9.00 29.000 1208.000
多个列表 6392.0 0.326 0.469 0.0 0.00 0.00 1.000 1.000
任何黑人 6390.0 0.282 0.450 0.0 0.00 0.00 1.000 1.000
地域列表 6392.0 9.514 9.277 1.0 2.00 6.00 14.000 53.000
黑人比例 6378.0 0.140 0.203 0.0 0.03 0.05 0.142 0.984

平衡处理测丨试(t 检验)显示黑人和白人客人是相同的。

result = []

for var in control:
    # Do the T-test and save the p-value
    pvalue = sm.OLS(df[var], df[['const', 'guest_black']],
               missing = 'drop').fit().pvalues[1]
    result.append(pvalue) 
ttest = df.groupby('guest_black').agg([np.mean])[control].T
ttest['p-value'] = result
ttest 
黑人客人 0.0 1.0 p 值
host_race_white 平均值 0.643 0.626 0.154
host_race_black 平均值 0.078 0.078 0.972
host_gender_F 平均值 0.381 0.372 0.439
host_gender_M 平均值 0.298 0.299 0.896
价丨格 平均值 166.429 195.815 0.362
卧室 平均值 3.178 3.176 0.962
浴室 平均值 3.172 3.167 0.927
评论数量 平均值 30.709 31.030 0.860
多个列表 平均值 0.321 0.330 0.451
任何黑人 平均值 0.287 0.277 0.382
地域列表 平均值 9.494 9.538 0.848
黑人比例 平均值 0.141 0.140 0.919

练习

1)据我所知,关于种族歧视的文献中最重要的三篇实证论文是 Bertrand & Mullainathan (2004), Oreopoulos (2011), 和 Edelman et al. (2017)。这三篇论文都使用了实地实验来捕捉因果关系并排除混杂因素。在互联网上搜索并返回一份关于种族歧视的实验论文的参考列表。

2)告诉我一个你热衷的话题。返回一个关于你的话题的实验论文的参考列表。

3)有人认为特定的名字驱动了 Edelman 等人(2017)的结果。在下面的表格中,你可以看到代表黑人和白人的名字并不多。如何反驳这个批评?你可以做什么来证明结果不是由特定的名字驱动的?

female = df['guest_gender']=='female'
df[female].groupby(['guest_race', 'guest_first_name'])['yes'].mean() 
guest_race  guest_first_name
black       Lakisha             0.433
            Latonya             0.370
            Latoya              0.442
            Tamika              0.482
            Tanisha             0.413
white       Allison             0.500
            Anne                0.567
            Kristen             0.486
            Laurie              0.508
            Meredith            0.498
Name: yes, dtype: float64 
male = df['guest_gender']=='male'
df[male].groupby(['guest_race', 'guest_first_name'])['yes'].mean() 
guest_race  guest_first_name
black       Darnell             0.412
            Jamal               0.354
            Jermaine            0.379
            Kareem              0.436
            Leroy               0.371
            Rasheed             0.409
            Tyrone              0.377
white       Brad                0.419
            Brent               0.494
            Brett               0.466
            Greg                0.467
            Jay                 0.581
            Todd                0.448
Name: yes, dtype: float64 

4)根据下表,是否有任何潜在的研究问题可以探讨?请证明。

pd.crosstab(index= [df['host_gender_F'], df['host_race']],
            columns=[df['guest_gender'], df['guest_race']], 
            values=df['yes'], aggfunc='mean') 
客人性别 女性 男性
客人种族 黑人 白人
host_gender_F host_race
0 UU 0.400 0.542
亚裔 0.319 0.378 0.474
黑人 0.444 0.643 0.419
西班牙裔 0.464 0.571 0.375
0.568 0.727 0.408
不明确 0.444 0.500 0.444
不明确的三票 0.476 0.392 0.368
白人 0.383 0.514 0.386
1 UU 0.444 0.250
亚裔 0.429 0.607 0.436
黑人 0.603 0.537 0.397
西班牙裔 0.391 0.667 0.292
不明确 0.600 0.556 0.125
不明确的三票 0.387 0.583 0.312
白人 0.450 0.494 0.370

5)在 Edelman 等人(2017 年)中,变量“name_by_city”被用来对标准误差进行聚类。变量“name_by_city”是如何基于其丨他变量创建的?展示代码。

6)使用 Edelman 等人(2017 年)的数据来测丨试同族偏好假设,即主人可能更喜欢相同种族的客人。使用 Stargazer 库生成一个漂亮的表格。解释结果。

7)总的来说,人们知道社丨会经济地位与种族有关。Fryer&Levitt(2004 年)表明,独特的非洲裔美丨国人名字与较低的社丨会经济地位相关。Edelman 等人(2017 年:17)明确表示:“我们的发现无法确定歧视是基于种族,社丨会经济地位,还是这两者的结合。”提出一个实验设计来分离种族和社丨会经济地位的影响。解释您的假设并详细描述程序。

参考

Bertrand,Marianne 和 Sendhil Mullainathan。 (2004)。艾米丽和格雷格比拉基莎和贾迈尔更受雇用吗?劳动市场歧视的实地实验。《美丨国经济评论》,94(4):991-1013。

Edelman,Benjamin,Michael Luca 和 Dan Svirsky。 (2017)。共享经济中的种族歧视:来自实地实验的证据。《美丨国经济学杂志:应用经济学》,9(2):1-22。

Fryer,Roland G. Jr.和 Steven D. Levitt。 (2004)。Distinctively Black Names 的原因和后果。《经济学季刊》,119(3):767–805。

Oreopoulos,Philip。 (2011)。为什么技术移民在劳动市场上挣扎?一项涉及一万三千份简历的实地实验。《美丨国经济学杂志:经济政策》,3(4):148-71。

九、股票市场如何缓解以巴冲突?

原文:causal-methods.github.io/Book/9%29_How_Can_Stock_Market_Mitigate_the_Israeli_Palestinian_Conflict.html

译者:飞龙

协议:CC BY-NC-SA 4.0

Vitor Kamada

电子邮件:[email protected]

最近更新:11-5-2020

“商业是最具破丨坏性偏见的良药。”(孟德斯鸠,1748 年:第 II 卷,第一章)

Jha & Shayo(2019)随机将 1345 名犹太以色列选民分为金融资产治疗组和对照组。他们报告称,接触股票市场会增加 4-6%的可能性,投票支持主张和平解决冲突的政党。让我们打开 Jha & Shayo(2019)的数据集。每一行都是以色列公民。

import numpy as np
import pandas as pd
pd.set_option('precision', 3)

# Data from Jha & Shayo (2019)
path = "https://github.com/causal-methods/Data/raw/master/" 
df = pd.read_stata(path + "replicationdata.dta")
df.head(5) 
C:\Anaconda\envs\textbook\lib\site-packages\pandas\io\stata.py:1433: UnicodeWarning: 
One or more strings in the dta file could not be decoded using utf-8, and
so the fallback encoding of latin-1 is being used.  This can happen when a file
has been incorrectly encoded by Stata or some other software. You should verify
the string values returned are correct.
  warnings.warn(msg, UnicodeWarning) 
统计 tradestock6 愿意承担 1 到 10 的风险 用户 ID 男性 关系 关系 ID nafa 教育 ses tradetot_m4 pricechange_m4 bought_bm4 sold_bm4 active_bm4 资产类型 上周 过去 3 年 下周 facts_0_m4
0 完成 NaN 3 60814.0 0.0 犹太教 世俗 耶路撒冷 硕士 平均以下 3.0 -0.673 0.0 0.0 0.0 1.0 0.0 0.0 1.0 2.0
1 完成 1.0 2 60824.0 0.0 犹太教 世俗 特拉维夫 文学士 平均以上 3.0 5.323 2.0 0.0 2.0 1.0 1.0 1.0 0.0 3.0
2 完成 0.0 3 61067.0 1.0 犹太教 世俗 中心 博士 平均以上 3.0 0.000 2.0 1.0 3.0 0.0 0.0 0.0 0.0 0.0
3 完成 NaN 4 61095.0 1.0 犹太教 世俗 海法 文学士学生 平均以下 3.0 5.323 3.0 2.0 3.0 0.0 0.0 1.0 0.0 1.0
4 完成 0.0 4 61198.0 1.0 犹太教 世俗 北部 硕士 平均以下 3.0 0.000 0.0 0.0 0.0 1.0 0.0 0.0 0.0 1.0

5 行×526 列

# Drop missing values
df = df.dropna(subset=['left_s3']) 

图 1 显示,2013 年选举中,对照组和治疗组的投票情况相似。但在 2015 年,左翼党派在对照组中获得了 24.8%的选票,而在治疗组中获得了 30.9%。相反,右翼党派在对照组中获得了 35.8%的选票,而在治疗组中获得了 31.2%。根据 Jha & Shayo(2019)的说法,右翼和左翼党派在经济政策方面是相似的。主要区别在于左翼党派支持和平进程,而右翼党派认为任何为和平做出的让步都会对以色列国家构成风险。

# Data: Vote Share by year
v2013 = df.groupby('assettreat')['left_2013', 'right_2013'].mean().T
v2015 = df.groupby('assettreat')['left_s3', 'right_s3'].mean().T
prop = v2013.append(v2015)

# Plot Bar Chart
import plotly.graph_objects as go
node = ['Left 2013', 'Right 2013', 'Left 2015', 'Right 2015']

fig = go.Figure(data=[             
    go.Bar(name='Control', x=node, y = prop[0]),
    go.Bar(name='Treatment', x=node, y = prop[1]) ])

fig.update_layout(barmode='group',
  title_text = 'Graphic 1 - Elections: 2013 vs 2015 ',
  font=dict(size=18) )

fig.update_yaxes(title_text = "Vote Share")

fig.show() 
C:\Anaconda\envs\textbook\lib\site-packages\ipykernel_launcher.py:2: FutureWarning: Indexing with multiple keys (implicitly converted to a tuple of keys) will be deprecated, use a list instead.

C:\Anaconda\envs\textbook\lib\site-packages\ipykernel_launcher.py:3: FutureWarning: Indexing with multiple keys (implicitly converted to a tuple of keys) will be deprecated, use a list instead.
  This is separate from the ipykernel package so we can avoid doing imports until 

下表显示,治疗组与对照组相似。例外情况是年龄和愿意承担风险。治疗组的以色列人比对照组年轻(39.3 岁对 41.5 岁)。治疗组在愿意承担风险方面也更偏好,评估指数从 1 到 10 变化(4.7 对 4.3)。

我们根据 OLS 回归和分层固定效应计算 p 值。

control = ['right_2013', 'left_2013', 'p_index_s1', 'e_index_init',
    'tradestock6all', 'male', 'age', 'postsecondary', 'BA_student',
	  'college_grad', 'married', 'r_sec',  'r_trad', 'r_relig', 'r_ultra', 
		'g_jerusalem', 'g_north', 'g_haifa', 'g_center', 'g_telaviv', 'g_south',
    'g_wb', 'faminc', 'willingrisk1to10', 'patient', 'plitscore'] 
import statsmodels.formula.api as smf

result = []
for var in control:
    # OLS with 104 randomization strata fixed effects
    reg = smf.ols(var + "~ 1 + assettreat + C(block13)", df)
    # 104 is the last variable: the coefficient of assettreat
    pvalue = reg.fit().pvalues[104]
    result.append(pvalue) 
C:\Anaconda\envs\textbook\lib\site-packages\statsmodels\tools\_testing.py:19: FutureWarning:

pandas.util.testing is deprecated. Use the functions in the public API at pandas.testing instead. 
table = df.groupby('assettreat')[control].mean().T  
table['p-value'] = result
table 
资产治疗 0.0 1.0 p 值
right_2013 0.245 0.241 0.964
left_2013 0.126 0.137 0.213
p_index_s1 0.004 0.051 0.399
e_index_init -0.005 0.007 0.752
tradestock6all 0.368 0.355 0.290
男性 0.513 0.521 0.470
年龄 41.530 39.289 0.011
高中后教育 0.232 0.230 0.953
文学士学生 0.152 0.148 0.834
大学毕业 0.427 0.426 0.860
已婚 0.629 0.598 0.295
r_sec 0.636 0.627 0.582
r_trad 0.172 0.164 0.823
r_relig 0.119 0.124 0.780
r_ultra 0.073 0.085 0.222
g_jerusalem 0.096 0.091 0.800
g_north 0.089 0.097 0.595
g_haifa 0.123 0.142 0.290
g_center 0.298 0.290 0.766
g_telaviv 0.212 0.194 0.276
g_south 0.116 0.104 0.596
g_wb 0.066 0.081 0.341
家庭收入 11162.162 10996.970 0.511
愿意承担风险 1 到 10 4.344 4.716 0.009
患者 0.642 0.657 0.645
plitscore 69.726 70.664 0.550
#  Library to print professional publication
# tables in Latex, HTML, etc.
!pip install stargazer 
Requirement already satisfied: stargazer in c:\anaconda\envs\textbook\lib\site-packages (0.0.5) 
WARNING: Error parsing requirements for numpy: [Errno 2] No such file or directory: 'c:\\anaconda\\envs\\textbook\\lib\\site-packages\\numpy-1.19.2.dist-info\\METADATA' 

表 1 的第 1 列显示了意向治疗(ITT)的估计值为 6.1%。值得一提的是,这种类型的实验很少有完全的遵从。通常,在需要随时间跟踪个体时,控制组和治疗组都会有一定的流失率。

第 2 列显示 ITT 效应对控制变量和分层固定效应的鲁棒性。

第 3 列使用变量“vote_wgt”作为权重呈现了加权最小二乘法(WLS)。Jha & Shayo(2019)提取了一个随机样本,其中非正统中心选民被过度抽样。逻辑是增加对最有趣的群体:摇摆选民的精度。使用权重可以在不过度抽样的情况下重现结果。

第 4 列显示结果是由接受以色列股票(“isrstock”)和投资券(“cash”)的治疗组个体驱动的。要小心得出巴勒斯坦股票没有影响的结论。在实验期间,以色列股票价丨格上涨,但巴勒斯坦股票下跌。

ITT1 = smf.ols("left_s3 ~ 1 + assettreat",
                 df).fit()

Xs = ['right_2013', 'left_2013', 'male', 'age', 'age2',
      'postsecondary', 'BA_student', 'college_grad',
      'married', 'tradestock6all', 'r_trad', 'r_relig',
      'r_ultra', 'g_jerusalem', 'g_north', 'g_haifa',
      'g_telaviv', 'g_south', 'g_wb', 'C(newses)',
      'willingrisk1to10', 'patient', 'plitscore']

controls = ""
for X in Xs:
    controls = controls + '+' + X      

ITT2 = smf.ols("left_s3 ~ 1 + assettreat" + controls +
                 "+C(block13)", df).fit()

WLS = smf.wls("left_s3 ~ 1 + assettreat" + controls +
       "+C(block13)", df, weights=df['vote_wgt']).fit()

treatments = "+ isrstock + palstock + cash"    
WLS2 = smf.wls("left_s3 ~ 1" + treatments + controls +
       "+C(block13)", df, weights=df['vote_wgt']).fit() 
# Settings for a nice table
from stargazer.stargazer import Stargazer
stargazer = Stargazer([ITT1, ITT2, WLS, WLS2])

stargazer.title('Table 1 - Intent to Treat Estimates of Stock'
   + ' Exposure on Voting for a Left Party')

names = ['ITT', 'ITT', 'WLS', 'WLS']
stargazer.custom_columns(names, [1, 1, 1, 1])

stargazer.covariate_order(['assettreat', 'isrstock',
                           'palstock', 'cash'])

stargazer.add_line('Strata Fixed Effects', ['No', 'Yes',
                                            'Yes', 'Yes'])
stargazer.add_line('Covariates', ['No', 'Yes', 'Yes', 'Yes'])

stargazer 

表 1 - 对左翼党投票的意向治疗估计股票暴露

资产处理
isrstock
palstock
现金
分层固定效应
协变量
观察
调整后的 R²
残差标准误差
F 统计量
注:

表 2 的第 1 列呈现了第一阶段回归。ITT(“资产处理”)是符合分配(“资产 _comp”)的工具变量(IV)。变量“资产 _comp”表示谁实际完成了实验。在控制了几个协变量和分层固定效应之后,ITT 的系数在统计上是显著的。变量“资产处理”是一个完美的 IV。这个变量是随机的。因此,它与误差项不相关。

第 2 列显示了控制函数方法(CF)的结果。对待处理的治疗效应(TOT)估计为 7.3%。接受治疗的个体投票给左翼党的概率增加了 7.3%。在这个框架中,CF 等同于 2SLS。在 CF 中,我们使用第一阶段的残差( u ^ \hat{u} u^)来控制第二阶段的内生性。注意残差在统计上是显著的。因此,需要进行修正。我们可以得出结论,表 1 低估了金融资产暴露对左翼党投票的影响。

# Fist Stage
FS = smf.ols("asset_comp ~ 1 + assettreat" + controls +
                 "+C(block13)", df).fit()

# Control Function Approach
df['resid'] = FS.resid
CF = smf.ols("left_s3 ~ 1 + asset_comp + resid" + controls +
                 "+C(block13)", df).fit() 
# Settings for a nice table
stargazer = Stargazer([FS, CF])

stargazer.title('Table 2 - Impact of Stock Exposure'
 ' on Voting for a Left Party')

names = ['First Stage', 'Control Function']
stargazer.custom_columns(names, [1, 1])

stargazer.covariate_order(['assettreat', 'asset_comp', 'resid'])

stargazer.add_line('Strata Fixed Effects', ['Yes', 'Yes'])
stargazer.add_line('Covariates', ['Yes', 'Yes'])

stargazer 

表 2 - 股票暴露对左翼党投票的影响

资产处理
资产 _comp
残差
分层固定效应
协变量
观察
调整后的 R²
残差标准误差
F 统计量
注:

练习

1)Jha&Shayo(2019)的样本由以色列选民组成。推测在巴勒斯坦选民的情况下,结果是否会在质量上相同。证明你的理由。

2)从 Jha&Shayo(2019)出发,有什么有前途的研究问题?

3)什么是社丨会期望偏差?描述 Jha&Shayo(2019)为减轻社丨会期望偏差所做的工作。

4)使用 2SLS 而不是控制函数方法复制表 2 的结果。不要使用库“linearmodels”。使用库“statsmodels”手动进行 2SLS。

5)暴露于巴勒斯坦股票是否会降低投票右翼政党的概率?运行一些回归来证明你的立场。

参考

Jha,S.和 Shayo,M.(2019)。估价和平:金融市场暴露对选票和政丨治态度的影响。计量经济学,87:1561-1588。

蒙特斯基耶,C.(1748)。法律精神。伦敦:T. Evans,1777 年,4 卷。第 2 卷。在线自由图书馆。

参考书目

原文:causal-methods.github.io/Book/Bibliography.html

译者:飞龙

协议:CC BY-NC-SA 4.0

作者:Vitor Kamada

电子邮件:[email protected]

最后更新日期 11-6-2020

书中使用的论文和数据:Python 因果推断。

巴斯滕,克里斯托夫和弗兰克贝茨(2013)。超越职业道德:宗丨教,个人和政丨治偏好。《美丨国经济学杂志:经济政策》,5(3):67-91。在线附录。finaldata.dta

贝克尔,萨沙 O.,和 Ludger Woessmann。 (2009)。韦伯错了吗?新教经济史的人力资本理论。《季度经济学杂志》124(2):531-96。

Bertrand,Marianne 和 Sendhil Mullainathan。 (2004)。艾米丽和格雷格比拉基莎和贾迈尔更受雇用吗?。劳动力市场歧视的实地实验。《美丨国经济评论》,94(4):991-1013。lakisha_aer.dta

Bisschop,Paul,Stephen Kastoryano 和 Bas van der Klaauw。 (2017)。街头卖丨淫区和犯罪。《美丨国经济学杂志:经济政策》,9(4):28-63。CBSregist2015.dta

Edelman,Benjamin,Michael Luca 和 Dan Svirsky。 (2017)。共享经济中的种族歧视:来自实地实验的证据。《美丨国经济学杂志:应用经济学》,9(2):1-22。Airbnb.csv

Fey,Mark,Richard D. McKelvey 和 Thomas R. Palfrey。 (1996)。恒定总和蜈蚣游戏的实验研究。《国际博弈理论杂志》,25(3):269-87。

弗莱尔,罗兰 G.,朱尼尔和史蒂文 D.莱维特。 (2004)。独特的黑人名字的原因和后果。《季度经济学杂志》119(3):767-805。

Imbens,G.,& Kalyanaraman,K.(2012)。回归断点估计器的最佳带宽选择。《经济研究评论》,79(3),933-959。

Jha,S.和 Shayo,M.(2019)。和平的价值:金融市场暴露对选票和政丨治态度的影响。计量经济学,87:1561-1588。replicationdata.dta

凯恩斯,约翰梅纳德。 (1936)。就业,利息和货币的一般理论。美丨国哈考特,布雷斯和公司出版,并由美丨国纽约波利图形公司印刷。

梅耶森,埃里克。 (2014)。伊丨斯丨兰统治与穷人和虔诚者的赋权。计量经济学,82(1),229-269。regdata0.dta

Montesquieu,C.(1748)。法的精神。伦敦:T. Evans,1777 年,4 卷。第 2 卷。在线自由图书馆。

Oreopoulos, Philip. (2011). 为什么技术移民在劳动市场上遇到困难?一项涉及一万三千份简历的实地实验. 美丨国经济学杂志:经济政策, 3 (4): 148-71. oreopoulos.dta

Palacios-Huerta, Ignacio, and Oscar Volij. (2009). 野外蜈蚣. 美丨国经济评论, 99 (4): 1619-35. Chess.xls

Richardson, Gary, and William Troost. (2009). 货币干预缓解了大萧条期间的银行恐慌:来自联邦储备区域边界的准实验证据,1929-1933. 政丨治经济学杂志 117 (6): 1031-73。

Weber, Max. (1930). 《新教伦理与资本主丨义精神》。纽约:斯克里布纳,(原始出版于 1905 年)。

Ziebarth, Nicolas L. (2013). 从密西西比州大萧条期间的自然实验中识别银行倒闭的影响. 美丨国经济学杂志:宏观经济学, 5 (1): 81-101. MS_data_all_years_regs.dta

你可能感兴趣的:(数据科学,python,开发语言)