【问题标题】:Difference in Differences in Python + PandasPython + Pandas 的差异差异
【发布时间】:2016-09-08 17:39:23
【问题描述】:

我正在尝试使用 Python 和 Pandas 执行Difference in Differences(带有面板数据和固定效果)分析。我没有经济学背景,我只是想过滤数据并运行我被告知的方法。但是,据我所知,我了解到基本的 diff-in-diffs 模型如下所示:

也就是说,我正在处理一个多变量模型。

这里遵循 R 中的一个简单示例:

https://thetarzan.wordpress.com/2011/06/20/differences-in-differences-estimation-in-r-and-stata/

可以看出,回归将一个因变量和一组观察结果作为输入。

我的输入数据如下所示:

    Name    Permits_13  Score_13    Permits_14  Score_14    Permits_15  Score_15
0   P.S. 015 ROBERTO CLEMENTE   12.0    284 22  279 32  283
1   P.S. 019 ASHER LEVY 18.0    296 51  301 55  308
2   P.S. 020 ANNA SILVER    9.0 294 9   290 10  293
3   P.S. 034 FRANKLIN D. ROOSEVELT  3.0 294 4   292 1   296
4   P.S. 064 ROBERT SIMON   3.0 287 15  288 17  291
5   P.S. 110 FLORENCE NIGHTINGALE   0.0 313 3   306 4   308
6   P.S. 134 HENRIETTA SZOLD    4.0 290 12  292 17  288
7   P.S. 137 JOHN L. BERNSTEIN  4.0 276 12  273 17  274
8   P.S. 140 NATHAN STRAUS  13.0    282 37  284 59  284
9   P.S. 142 AMALIA CASTRO  7.0 290 15  285 25  284
10  P.S. 184M SHUANG WEN    5.0 327 12  327 9   327

通过一些研究,我发现这是在 Pandas 中使用固定效果和面板数据的方法:

Fixed effect in Pandas or Statsmodels

我执行了一些转换以获得多索引数据:

rng = pandas.date_range(start=pandas.datetime(2013, 1, 1), periods=3, freq='A')
index = pandas.MultiIndex.from_product([rng, df['Name']], names=['date', 'id'])
d1 = numpy.array(df.ix[:, ['Permits_13', 'Score_13']])
d2 = numpy.array(df.ix[:, ['Permits_14', 'Score_14']])
d3 = numpy.array(df.ix[:, ['Permits_15', 'Score_15']])
data = numpy.concatenate((d1, d2, d3), axis=0)
s = pandas.DataFrame(data, index=index)  
s = s.astype('float')

但是,我不知道如何将所有这些变量传递给模型,例如可以在 R 中完成:

reg1 = lm(work ~ post93 + anykids + p93kids.interaction, data = etc)

这里,13、14、15 代表 2013、2014、2015 年的数据,我认为应该使用这些数据来创建面板。 我这样称呼模型:

reg  = PanelOLS(y=s['y'],x=s[['x']],time_effects=True)

结果如下:

(一位经济学家)告诉我,这似乎没有固定效应。

--编辑--

我要验证的是在给定时间的情况下,许可证数量对分数的影响。许可证的数量是治疗,是强化治疗

可以在此处找到代码示例:https://www.dropbox.com/sh/ped312ur604357r/AACQGloHDAy8I2C6HITFzjqza?dl=0

【问题讨论】:

  • 我没有仔细看你在做什么,但是使用公式界面你可以让 patsy 完成创建虚拟变量和交互效果的所有工作。
  • 您不需要正式“声明”面板数据来执行差异回归的差异(从技术上讲,它是基本的 OLS 回归),pandas 数据框就可以了。关于 R 风格的公式,您只需阅读以下内容:statsmodels.sourceforge.net/devel/example_formulas.html
  • 我知道我必须使用熊猫才能使用固定面板,@etna:stackoverflow.com/questions/29065097/pandas-with-fixed-effects
  • 如果您解释了您的研究问题和数据,会更容易提供帮助。差异中的差异旨在调查“治疗”的结果:您要调查的治疗是什么?您想在哪个变量上衡量治疗的影响?
  • 你是对的,@etna。我现在试着解释。谢谢。

标签: python pandas regression least-squares panel-data


【解决方案1】:

看来您需要的不是差异(DD)回归的差异。当您可以区分对照组和治疗组时,DD 回归是相关的。一个标准的简化示例是对药物的评估。你把一群病人分成两组。其中一半没有得到任何东西:他们是对照组。另一半被给予药物:他们是治疗组。从本质上讲,DD 回归将捕捉到这样一个事实,即药物的实际效果无法直接衡量,即有多少人服用该药物后变得健康。直觉上,你想知道这些人是否比那些没有服用任何药物的人做得更好。这个结果可以通过添加另一个类别来改进:安慰剂组,即给予看起来像药物但实际上不是药物的人......但这又是一个明确定义的群体。最后但并非最不重要的一点是,要使 DD 回归真正合适,您需要确保组不是异质的,以免导致结果产生偏差。如果治疗组只包括年轻且超级健康的人(因此通常更容易治愈),而对照组是一群老酗酒者,那么您的医学测试会遇到一个糟糕的情况......

在你的情况下,如果我没记错的话,每个人都会在某种程度上得到“治疗”......所以你更接近标准回归框架,其中 X 对 Y(例如智商对工资)的影响是测量。我知道您想衡量许可证数量对分数的影响(或者相反?-_-),并且您需要处理经典的内生性,即如果彼得比保罗更熟练,他会通常获得更多的许可和更高的分数。所以你真正想要使用的是,随着时间的推移,拥有相同水平的技能,彼得(分别是保罗)多年来将被“授予”不同级别的许可证......你将真正衡量许可证的影响得分...

我可能猜得不好,但我想坚持这样一个事实,即如果您没有付出足够的努力来理解/解释数据中发生的事情,那么有很多方法可以获得有偏见的结果,因此毫无意义。关于技术细节,您的估计只有年份固定效应(可能没有估计但通过贬低考虑,因此不会在输出中返回),所以您要做的是添加entity_effects = True。如果你想走得更远......恐怕到目前为止,任何 Python 包都没有很好地涵盖面板数据回归,(包括 statsmodels,如果你不想投资的话......我宁愿建议使用R或Stata。同时,如果您只需要一个固定效应回归,您还可以使用 statsmodels 获得它(如果需要,它还允许对标准错误进行聚类......):

import statsmodels.formula.api as smf
df = s.reset_index(drop = False)
reg = smf.ols('y ~ x + C(date) + C(id)',
              data = df).fit()
print(reg.summary())
# clustering standard errors at individual level
reg_cl = smf.ols(formula='y ~ x + C(date) + C(id)',
                 data=df).fit(cov_type='cluster',
                              cov_kwds={'groups': df['id']})
print(reg_cl.summary())
# output only coeff and standard error of x
print(u'{:.3f} ({:.3f})'.format(reg.params.ix['x'], reg.bse.ix['x']))
print(u'{:.3f} ({:.3f})'.format(reg_cl.params.ix['x'], reg_cl.bse.ix['x']))

关于计量经济学,您可能会在 Cross Validated 上得到比这里更多/更好的答案。

【讨论】:

  • 感谢您的详细回答,@etna。我没有将其视为 diff-in-diffs 问题,但有人告诉我这是一种“强化治疗”,并且要编写此方法...
  • 对于 # 仅输出 x 的系数和标准错误,它不适用于 ix,所以我尝试使用 iloc 并收到此错误:索引器太多。有什么想法吗?
  • 我在print(reg_cl.summary()) 之前一直这样做,但我收到了这个:约束的协方差没有满秩。约束数量为 3027,但排名为 7 个警告。 warn('约束的协方差不完整。这部分(仅输出 x 的系数和标准误差)对我不起作用!
猜你喜欢
  • 2011-01-05
  • 2023-02-25
  • 2020-06-19
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多