前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >Python 因果推断(下)

Python 因果推断(下)

作者头像
ApacheCN_飞龙
发布2024-01-31 10:02:00
1520
发布2024-01-31 10:02:00
举报
文章被收录于专栏:信数据得永生信数据得永生

六、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

电子邮件:econometrics.methods@gmail.com

最近更新:2020 年 9 月 15 日

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

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

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

代码语言:javascript
复制
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 列

代码语言:javascript
复制
# Transform the variable of interest in % 
df["callback"] = 100*df["callback"] 

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

代码语言:javascript
复制
# Restrict data to April and August 2008
df0 = df[(df.fall_data == 0)] 

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

代码语言:javascript
复制
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)的发现。在他的论文中,女性的系数在大部分回归中都不具有统计学显著性。

代码语言:javascript
复制
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 月之间进行的。这是大萧条的最糟糕时期。

代码语言:javascript
复制
# Restrict data to February and September 2009
df2 = df[(df.fall_data == 2)] 

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

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

代码语言:javascript
复制
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

代码语言:javascript
复制
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%。白人男性的名字比中国和印度男性的名字有优势,但幅度不像白人男性与白人女性之间的差异那么大。

代码语言:javascript
复制
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

代码语言:javascript
复制
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)随机化的。控制变量表明,女性和男性彼此相似。

代码语言:javascript
复制
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

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

代码语言:javascript
复制
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_{rjt}

是一个虚拟变量,如果简历

r

发送到工作

j

在时间

t

收到回电,则为 1;否则为 0。感兴趣的变量是“女性”虚拟变量和与“简历类型”的交互。

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

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

y_{rjt}= \beta Female_{rjt}+\gamma Resume\ Types_{rjt}+ \delta Female_{rjt} \cdot Resume\ Types_{rjt} + \alpha X + \epsilon_{rjt}

其中

X

是控制变量的向量,

\epsilon_{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)报告的主要发现相匹配。

代码语言:javascript
复制
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) 
代码语言:javascript
复制
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. 
代码语言:javascript
复制
#  Library to print professional publication
# tables in Latex, HTML, etc.
!pip install stargazer 
代码语言:javascript
复制
Requirement already satisfied: stargazer in c:\anaconda\envs\textbook\lib\site-packages (0.0.5) 
代码语言:javascript
复制
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' 
代码语言:javascript
复制
# 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 相比在统计上不太显着。这种模式表明,白人男性比印度人和中国姓氏的人有优势,但不包括希腊人或中国人(名字和姓氏)。这两个最后一组的系数在统计上不显着。

代码语言:javascript
复制
model2 = "callback ~ female*C(type)"

result2 = []
for data in sample:
   ols = smf.ols(model2, data).fit(cov_type='HC1')
   result2.append(ols) 
代码语言:javascript
复制
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,只有印度回归的系数在统计上显着。白人男性的名字与中国,中国加拿大和希腊名字没有优势。

代码语言:javascript
复制
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) 
代码语言:javascript
复制
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)你能从下表推断出什么?你有什么见解要分享吗?

代码语言:javascript
复制
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)你能从下表推断出什么?你有什么见解要分享吗?

代码语言:javascript
复制
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 的结果。重点关注固定效应(职业,姓名和城市)的添加。

代码语言:javascript
复制
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) 
代码语言:javascript
复制
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 
代码语言:javascript
复制
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

电子邮件:econometrics.methods@gmail.com

最近更新:2020 年 11 月 2 日

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

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

代码语言:javascript
复制
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。

代码语言:javascript
复制
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 名居民的年度犯罪报告。总体而言,大城市的犯罪率更高。唯一的例外是与毒丨品有关的犯罪。

代码语言:javascript
复制
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 个组相似。

代码语言:javascript
复制
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。

代码语言:javascript
复制
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

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

代码语言:javascript
复制
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_{ct}

为城市

c

在年份

t

的犯罪率。设

D_{ct}

= 1,如果城市

c

在年份

t

有开放的 tippelzone;否则为 0。让我们估计以下模型:

ln(Y_{ct})=\alpha_c+\rho D_{ct}+\beta X_{ct}+\gamma_t + \epsilon_{ct}

其中

\alpha_c

是城市固定效应,

X_{ct}

是控制变量向量,

\gamma_t

是年固定效应,

\epsilon_{ct}

是通常的误差项。

代码语言:javascript
复制
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) 
代码语言:javascript
复制
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 
代码语言:javascript
复制
#  Library to print professional publication
# tables in Latex, HTML, etc.
!pip install stargazer 
代码语言:javascript
复制
Requirement already satisfied: stargazer in c:\anaconda\envs\textbook\lib\site-packages (0.0.5) 
代码语言:javascript
复制
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

)。在其丨他列中,tippelzone 的系数在统计上不显著。看起来合法化卖丨淫会减少性丨虐丨待,但不会减少其丨他犯罪,如强丨奸、攻击、非法武器和毒丨品相关犯罪。

代码语言:javascript
复制
# 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 
代码语言:javascript
复制
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 统计量

注意:

代码语言:javascript
复制
import math
math.exp(-0.302) - 1 
代码语言:javascript
复制
-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)表示:“…时间趋势

\mu_t

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

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

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

i) “everopenNoReg”: 如果城市

c

在年份

t

之前曾开放过没有许可证的 tippelzone,则为 1,否则为 0。

ii) “openingRegP”: 如果城市

c

在年份

t

之前开放了 tippelzone 并引入了事后许可证,则为 1,否则为 0。

iii) “openingRegA”: 如果城市

c

在年份

t

之前曾开放过带有许可证的 tippelzone,则为 1,否则为 0。

iv) “closing”: 如果城市

c

在年份

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

电子邮件:econometrics.methods@gmail.com

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

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

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

代码语言:javascript
复制
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)的结果是由主人回应的差异驱动的,比如有条件的或非回应。例如,你可以争辩说黑人更有可能有被归类为垃丨圾邮件的假账户。然而,请注意,歧视结果是由“是”和“否”驱动的,而不是由中间回应驱动的。

代码语言:javascript
复制
# 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)的主要结果。

代码语言:javascript
复制
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] 
代码语言:javascript
复制
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. 
代码语言:javascript
复制
#  Library to print professional publication
# tables in Latex, HTML, etc.
!pip install stargazer 
代码语言:javascript
复制
Requirement already satisfied: stargazer in c:\anaconda\envs\textbook\lib\site-packages (0.0.5) 
代码语言:javascript
复制
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 列的一组控制变量中非常稳健。

代码语言:javascript
复制
# 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 统计量

注:

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

代码语言:javascript
复制
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 检验)显示黑人和白人客人是相同的。

代码语言:javascript
复制
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) 
代码语言:javascript
复制
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)的结果。在下面的表格中,你可以看到代表黑人和白人的名字并不多。如何反驳这个批评?你可以做什么来证明结果不是由特定的名字驱动的?

代码语言:javascript
复制
female = df['guest_gender']=='female'
df[female].groupby(['guest_race', 'guest_first_name'])['yes'].mean() 
代码语言:javascript
复制
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 
代码语言:javascript
复制
male = df['guest_gender']=='male'
df[male].groupby(['guest_race', 'guest_first_name'])['yes'].mean() 
代码语言:javascript
复制
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)根据下表,是否有任何潜在的研究问题可以探讨?请证明。

代码语言:javascript
复制
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

电子邮件:econometrics.methods@gmail.com

最近更新:11-5-2020

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

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

代码语言:javascript
复制
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) 
代码语言:javascript
复制
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 列

代码语言:javascript
复制
# Drop missing values
df = df.dropna(subset=['left_s3']) 

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

代码语言:javascript
复制
# 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() 
代码语言:javascript
复制
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 值。

代码语言:javascript
复制
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'] 
代码语言:javascript
复制
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) 
代码语言:javascript
复制
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. 
代码语言:javascript
复制
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

代码语言:javascript
复制
#  Library to print professional publication
# tables in Latex, HTML, etc.
!pip install stargazer 
代码语言:javascript
复制
Requirement already satisfied: stargazer in c:\anaconda\envs\textbook\lib\site-packages (0.0.5) 
代码语言:javascript
复制
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”)的治疗组个体驱动的。要小心得出巴勒斯坦股票没有影响的结论。在实验期间,以色列股票价丨格上涨,但巴勒斯坦股票下跌。

代码语言:javascript
复制
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() 
代码语言:javascript
复制
# 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 中,我们使用第一阶段的残差(

\hat{u}

)来控制第二阶段的内生性。注意残差在统计上是显著的。因此,需要进行修正。我们可以得出结论,表 1 低估了金融资产暴露对左翼党投票的影响。

代码语言:javascript
复制
# 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() 
代码语言:javascript
复制
# 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

电子邮件:econometrics.methods@gmail.com

最后更新日期 11-6-2020

本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2024-01-30,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 六、2007-2009 年大衰退期间加拿大就业市场上白人女性名字的溢价
    • 练习
      • 参考
      • 七、卖丨淫合法化对犯罪的影响
        • 练习
          • 参考
          • 八、Airbnb 的主人是否歧视黑人客人?
            • 练习
              • 参考
              • 九、股票市场如何缓解以巴冲突?
                • 练习
                  • 参考
                  • 参考书目
                  领券
                  问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档