Experiments and Quasi-Experiments(실험/준실험 연구)3 > Difference-in-Difference(이중차분법)

2020. 11. 29. 21:22계량경제학

반응형

이번 포스팅에서는 앞서 정리하였던 Instrumental Variable과 더불어 실증연구에서 활발히 활용되고 있는 Difference-in-Difference(DiD)에 대해서 정리해보도록 하겠습니다.

DiD는 준실험연구 환경에서 적용되는 방법론이며, 특정한 Intervention이나 Treatment의 효과를 측정하기 위해 적용되는 방법론입니다. Treatement group과 Control group에서의 시간의 흐름에 따른 변화량을 비교함으로써 효과를 추정하게 됩니다.

https://www.publichealth.columbia.edu/research/population-health-methods/difference-difference-estimation

그림에서 Intervention effect가 바로 DiD를 추정함으로써 얻는 값이 됩니다. DiD 추정값은 아래와 같이 표현될 수 있습니다.

즉 위 추정량은 시간에 따른 Treatment 그룹에서의 변화량과 Control 그룹에서의 변화량을 비교하면, 순수한 Treatment 효과를 추정해 낼 수 있다는 것을 의미합니다. 여기서 $\overline{Y}$은 Sample average를 뜻합니다.

DiD방법론을 적용하기 위해서는 Pre-/Post-Treatment 모두에 해당하는 데이터가 필요합니다. DiD를 적용하기 위한 주요 가정으로는, Parallel Trend Assumption이 있습니다. 이 가정은 만약 Treatment/Intervention이 없다면, 각 그룹간 시간에 따른 변화량차이가 일정해야 한다는 가정입니다. 이는 주로 시각화를 통해 확인합니다.

DiD 회귀 모형은 다음과 같습니다.

$$Y=\beta_0+\beta_1*Time+\beta_2*Intervention+\beta3(Time*Intervention)+\beta_4Covariates+\varepsilon $$

계수에 대한 해석은 아래와 같습니다.

https://www.publichealth.columbia.edu/research/population-health-methods/difference-difference-estimation
https://www.publichealth.columbia.edu/research/population-health-methods/difference-difference-estimation

DiD를 통해서 우리가 최종적으로 추정하고자 하는 것은 $\beta_3$로 이것이 Treatment에 대한 효과가 됩니다.

Python을 통해 가볍게 실습을 진행해보겠습니다. 이번 실습은 github.com/hmelberg/causal을 참조하였습니다. 해당 데이터는 노르웨이 데이터의 의료진 방문 데이터입니다. 노르웨이에서는 2010년부터 16살 아래인 사람들에게 의료진을 방문할때 Copayment(부담금)을 제거했는데, 해당 데이터를 활용하여 Copayment제거라는 이벤트가 어떤 영향력을 가졌는지를 DiD를 통해 분석해보겠습니다.

# read file
file="https://www.dropbox.com/s/5w4l7fvus79wvew/femaleVisitsToPhysician.csv?dl=1"
df=pd.read_csv(file)
df.columns ## Index(['Unnamed: 0', 'year', 'age', 'sex', 'consultations', 'population','perCapita', 'visits'] 
df.head()
'''
   Unnamed: 0  year  age sex  consultations  population  perCapita   visits
0           4  2006    1   f        67194.0     28221.0   2.380993  67194.0
1           7  2006    2   f        49802.0     28361.0   1.756003  49802.0
2          10  2006    3   f        42741.0     27899.0   1.531990  42741.0
3          13  2006    4   f        36555.0     28420.0   1.286242  36555.0
4          16  2006    5   f        33319.0     29479.0   1.130262  33319.0
'''


## 14살, 25살 비교
df2 = df.query('age==14 or age==25')
df2 = df2[['year', 'age', 'perCapita']]
df2.set_index(['year', 'age']).unstack('age').plot()

먼저 데이터를 불러옵니다. 해당 데이터에서 중요한 Column은 age, year, perCapita이며 perCapita는 해당 년도에, 해당 나이의 인구수 대비 의료진 방문수입니다.(=consultations/population)

우리는 여기서 임의로 14살 그룹과 25살 그룹만을 비교하여 Copayment를 제거한 영향력을 분석하고자 합니다. 따라서 14살, 25살 그룹에 대해 Parallel Trend Assumption를 확인하기 위해 Plotting을 수행해보았습니다.  2009년까지는 비슷하게 움직이다가 2010년부터는 움직임이 조금 달라짐을 확인 할 수 있습니다. DiD 분석을 계속 수행해 보겠습니다.

df14and25 = df2.set_index(['year', 'age']).unstack('age')
df14and25

'''
     perCapita          
age         14        25
year                    
2006  0.941863  2.724488
2007  0.970424  2.883638
2008  0.976127  2.969386
2009  1.012518  3.076277
2010  1.171481  3.018165
2011  1.262579  3.011706
2012  1.250965  3.052795
2013  1.296148  3.019887

'''
df14and25['copay'] = 0
df14and25['copay'] = df14and25.copay.where(df14and25.index<2010, 1)
df14and25

'''
     perCapita           copay
age         14        25      
year                          
2006  0.941863  2.724488     0
2007  0.970424  2.883638     0
2008  0.976127  2.969386     0
2009  1.012518  3.076277     0
2010  1.171481  3.018165     1
2011  1.262579  3.011706     1
2012  1.250965  3.052795     1
2013  1.296148  3.019887     1
'''
## 그룹간 평균 차이 비교
result = df14and25.groupby('copay').mean()
result.columns = ['age_14', 'age_25']
result

'''
         age_14    age_25
copay                    
0      0.975233  2.913447
1      1.245293  3.025638
'''

result['age_14'] - result['age_25']
'''
copay
0   -1.938214
1   -1.780345
'''
(result['age_14'] - result['age_25']).diff()

'''
copay
0         NaN
1   0.157869
'''

(result['age_14'] - result['age_25']).diff()를 통해서 얻어진 결과 0.157869는 위에서 정리했던 DiD 추정값과 같습니다.

즉 0.157869란 값은 Copayment가 제거됐을 때, Treatment그룹에 가지는 순수한 효과를 나타냅니다. 여기서는 인구당 방문횟수를 0.157869정도 증가시키는 것으로 볼 수 있을 것입니다.

마지막으로 회귀분석을 통해 DiD를 추정해보겠습니다.

df2
'''
     year  age  perCapita
13   2006   14   0.941863
24   2006   25   2.724488
102  2007   14   0.970424
113  2007   25   2.883638
191  2008   14   0.976127
202  2008   25   2.969386
280  2009   14   1.012518
291  2009   25   3.076277
369  2010   14   1.171481
380  2010   25   3.018165
458  2011   14   1.262579
469  2011   25   3.011706
547  2012   14   1.250965
558  2012   25   3.052795
636  2013   14   1.296148
647  2013   25   3.019887
'''

df2['copay']=0
df2['copay']=df2['copay'].where(df2.year<2010,1)
df2['age_14'] = np.where(df2.age==14,1,0)

## DiD
mod = smf.ols('perCapita~age_14+copay+copay*age_14+year', data = df2).fit()
mod.summary()

'''
================================================================================
                   coef    std err          t      P>|t|      [0.025      0.975]
--------------------------------------------------------------------------------
Intercept      -85.7891     26.764     -3.205      0.008    -144.696     -26.882
age_14          -1.9382      0.042    -45.974      0.000      -2.031      -1.845
copay           -0.0646      0.068     -0.950      0.363      -0.214       0.085
copay:age_14     0.1579      0.060      2.648      0.023       0.027       0.289
year             0.0442      0.013      3.314      0.007       0.015       0.074
==============================================================================
'''

회귀분석을 이용하여 추정한 copay:age_14(Treatment 효과)값도 앞에서 손으로 추정했던 것과 일치함을 확인할 수 있습니다.

 

참고)

www.publichealth.columbia.edu/research/population-health-methods/difference-difference-estimation

github.com/hmelberg/causal

반응형