Разница в различиях в Python + Pandas

Я пытаюсь выполнить анализ Разница в различиях (с панельными данными и фиксированными эффектами) с использованием Python и панды. У меня нет экономического образования, и я просто пытаюсь отфильтровать данные и запустить метод, который мне сказали. Однако, насколько я мог узнать, я понял, что базовая модель 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:

Исправлен эффект в Pandas или Statsmodels

Я выполнил некоторые преобразования, чтобы получить данные Multi-index:

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.


person pceccon    schedule 12.05.2016    source источник
comment
Я не смотрел внимательно на то, что вы делаете, но с помощью интерфейса формул вы можете позволить patsy сделать всю работу по созданию фиктивных переменных и эффектов взаимодействия.   -  person Josef    schedule 12.05.2016
comment
Вам не нужно официально объявлять панельные данные для выполнения регрессии различий в различиях (технически это базовая регрессия OLS), подойдет кадр данных pandas. Что касается формул в стиле R, вам просто нужно прочитать это: statsmodels.sourceforge.net/devel/example_formulas. html   -  person etna    schedule 12.05.2016
comment
Я понял, что мне пришлось использовать панды для использования фиксированной панели, @etna: stackoverflow.com/questions/29065097/pandas-with-fixed-effects   -  person pceccon    schedule 14.05.2016
comment
Было бы легче помочь, если бы вы объяснили свои исследовательские вопросы и данные. Различия в различиях предназначены для исследования результатов лечения: какое лечение вы хотите исследовать? По какой переменной вы хотите измерить воздействие лечения?   -  person etna    schedule 17.05.2016
comment
Ты права, @этна. Я попытался сейчас объяснить. Спасибо.   -  person pceccon    schedule 18.05.2016


Ответы (1)


Кажется, что вам нужна не разница в различиях (DD) регрессии. Регрессии DD уместны, когда вы можете различить контрольную группу и группу лечения. Стандартным упрощенным примером может быть оценка лекарства. Вы делите группу больных людей на две группы. Половине ничего не дают: это контрольная группа. Другой половине дают лекарство: это лечебная группа. По сути, регрессия DD будет отражать тот факт, что реальный эффект лекарства нельзя измерить напрямую с точки зрения того, сколько людей, которым давали лекарство, стали здоровыми. Интуитивно вы хотите знать, были ли эти люди лучше, чем те, которым не давали никаких лекарств. Этот результат можно уточнить, добавив еще одну категорию: плацебо, то есть людей, которым дают что-то похожее на лекарство, но на самом деле им не являющееся... но опять же, это будет четко определенная группа. И последнее, но не менее важное: для того, чтобы регрессия DD была действительно подходящей, вы должны убедиться, что группы не являются гетерогенными таким образом, что это может привести к искажению результатов. Плохая ситуация для вашего медицинского теста будет, если в группу лечения входят только люди, которые молоды и в отличной форме (следовательно, в целом больше шансов на выздоровление), в то время как контрольная группа состоит из старых алкоголиков...

В вашем случае, если я не ошибаюсь, в той или иной степени лечат всех... так что вы ближе к стандартной схеме регрессии, в которой должно быть измерено влияние X на Y (например, IQ на заработную плату). Я понимаю, что вы хотите измерить влияние количества разрешений на счет (или наоборот? -_-), и вам нужно иметь дело с классической эндогенностью, т.е. если Петр более квалифицирован, чем Пол, он обычно получают больше разрешений И более высокий балл. Итак, что вы на самом деле хотите использовать, так это тот факт, что с одним и тем же уровнем навыков с течением времени Петру (соответственно Павлу) будут даваться разные уровни разрешений на протяжении многих лет... и там вы действительно измерите влияние разрешений на счет. ...

Возможно, я плохо угадываю, но я хочу настоять на том факте, что есть много способов получить предвзятые и, следовательно, бессмысленные результаты, если вы не приложите достаточно усилий, чтобы понять/объяснить, что происходит в данных. Что касается технических деталей, ваша оценка имеет только фиксированные годовые эффекты (вероятно, не оцененные, но принятые во внимание путем унижения, поэтому не возвращаются в выходных данных), поэтому вам нужно добавить entity_effects = True. Если вы хотите пойти дальше... Я боюсь, что регрессии панельных данных до сих пор недостаточно хорошо описаны ни в одном пакете Python (включая статистические модели, которые являются справочником по эконометрике), поэтому, если вы не хотите инвестировать... скорее предложил бы использовать R или Stata. Между тем, если регрессия с фиксированным эффектом - это все, что вам нужно, вы также можете получить ее с помощью статистических моделей (которые также позволяют кластеризовать стандартные ошибки, если это необходимо...):

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, чем здесь.

person etna    schedule 18.05.2016
comment
Спасибо за подробный ответ, @etna. Я не видел в этом проблему diff-in-diffs, но мне сказали, что это интенсивное лечение и кодировать этот метод... - person pceccon; 19.05.2016