2020. 10. 24. 23:41ㆍ계량경제학
Panel 회귀모형을 활용하면, 이전 포스팅에서 언급했던 Omitted variable과 같은 이슈를 일부 해소할 수 있습니다. 만약 Omitted variable이 있고 해당 Omitted variable이 무엇인지 정확히 알기 어려울 때, Panel 회귀모형을 활용하면 시간 또는 그룹차원에서 Parameter 추정에 왜곡을 주는 요소를 회귀분석에 포함하여 분석할 수 있습니다.
먼저 Panel 데이터는 $n$개의 entities로만 구성되어 있는 Cross-section 데이터와 다르게, $n$개의 entities와 시간 T로 구성되어 있습니다.
$$(X_{it}, Y_{it}), i=1,\cdots ,n \,\,and\,\, t =1,\cdots,T $$
예시를 통해, Panel 데이터 및 상이한 시간대에 따른 회귀분석의 Parameter가 어떻게 변하는지 알아보겠습니다.
## Data load
Fatalities = pd.read_csv("Fatalities.csv")
Fatalities.info()
Fatalities["fatal_rate"] = (Fatalities["fatal"] / Fatalities["pop"]) * 10000
Fatal_1982 = Fatalities.loc[Fatalities["year"]==1982]
Fatal_1988 = Fatalities.loc[Fatalities["year"]==1988]
## simple regression model
fatal_1982_mod = smf.ols("fatal_rate~beertax", data=Fatal_1982).fit()
fatal_1982_mod.summary()
'''
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
Intercept 2.0104 0.139 14.455 0.000 1.730 2.290
beertax 0.1485 0.188 0.788 0.435 -0.231 0.528
==============================================================================
'''
fatal_1988_mod = smf.ols("fatal_rate~beertax", data=Fatal_1988).fit()
fatal_1988_mod.summary()
'''
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
Intercept 1.8591 0.106 17.540 0.000 1.646 2.072
beertax 0.4388 0.164 2.668 0.011 0.108 0.770
==============================================================================
'''
sns.regplot(x="beertax", y="fatal_rate", data=Fatal_1982)
plt.title("Traffic Fatality Rates and Beer Taxes in 1982")
sns.regplot(x="beertax", y="fatal_rate", data=Fatal_1988, color="orange")
plt.title("Traffic Fatality Rates and Beer Taxes in 1988")
추정된 계수를 보면, 1988년의 데이터를 활용한 Parameter값이 1982년의 데이터를 활용한 Parameter값보다 거의 3배가 큰 것을 확인할 수 있습니다. 이와 같이 시간대를 활용하면 기존 Cross-section에서 잡아내지 못하는 효과를 분석해볼 수 있습니다.
[Fixed effect 회귀분석]
앞서 말한것과 같이 Panel 회귀모형은 연구자가 관찰하기 어려운 요인들을 통제하여 또는 포함하여 분석하는 방법인다. Fixed effect 회귀분석은 One-way Fixed 모델과 Two-way Fixed 모델로 나눠질 수 있는데 One-way Fixed 모델은 time-invariant한 각 Entity가지는 특성을 포함하는 것이고, Two-way Fixed 모델은 각 Entity가 가지는 특성 및 시간에 따라 변화하는 요인까지 포함한 모델입니다.
아래와 같은 회귀분석 모형을 고려해보겠습니다.
$$ Y_{it} = \beta_0 + \beta_1 X_{it} + \beta_2 Z_i +\mu_{it} $$
이 때 $Z_i$은 time-invariant한 관찰되지 않은 요인을 나타냅니다. $\alpha_i = \beta_0 +\beta_2 Z_i$ 라고 한다면 위의 식은 다시 아래와 같이 표현될 수 있습니다.
또한 위의 식은 Dummy 회귀분석으로 표현할 수 있습니다.
그런데 위와 같이 모든 Dummy variable을 활용하여 우리가 관심있는 $\beta_1$을 추정하는 것은 비효율적이기 때문에 "entity-demeaned" 방법을 활용하여 계수를 추정하게 됩니다.
최종적으로 아래와 같이 정리될 수 있습니다.
이제 Dummy 회귀분석과 entity-demeaned 방법을 활용한 회귀분석을 통해서 계수를 비교해보도록 하겠습니다.
## dummy regression
fatal_fe_lm_mod = smf.ols("fatal_rate~beertax+state-1", data=Fatalities).fit()
fatal_fe_lm_mod.summary()
## entity-demeaned
Fatalities_demeaned = pd.DataFrame()
Fatalities_demeaned["fatal_rate"] = Fatalities["fatal_rate"]-Fatalities.groupby("state")["fatal_rate"].transform("mean")
Fatalities_demeaned["beertax"] = Fatalities["beertax"]-Fatalities.groupby("state")["beertax"].transform("mean")
smf.ols("fatal_rate~ beertax -1", data=Fatalities_demeaned).fit().summary()
'''
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
state[al] 3.4776 0.313 11.098 0.000 2.861 4.094
state[ar] 2.8227 0.132 21.364 0.000 2.563 3.083
state[az] 2.9099 0.093 31.445 0.000 2.728 3.092
state[ca] 1.9682 0.074 26.594 0.000 1.822 2.114
state[co] 1.9933 0.080 24.802 0.000 1.835 2.152
state[ct] 1.6154 0.084 19.251 0.000 1.450 1.781
state[de] 2.1700 0.077 28.016 0.000 2.018 2.322
state[fl] 3.2095 0.222 14.489 0.000 2.774 3.645
state[ga] 4.0022 0.464 8.625 0.000 3.089 4.916
state[ia] 1.9337 0.102 18.918 0.000 1.733 2.135
state[id] 2.8086 0.099 28.437 0.000 2.614 3.003
state[il] 1.5160 0.078 19.318 0.000 1.362 1.670
state[in] 2.0161 0.089 22.736 0.000 1.842 2.191
state[ks] 2.2544 0.109 20.753 0.000 2.041 2.468
state[ky] 2.2601 0.080 28.089 0.000 2.102 2.418
state[la] 2.6305 0.163 16.171 0.000 2.310 2.951
state[ma] 1.3679 0.086 15.818 0.000 1.198 1.538
state[md] 1.7712 0.082 21.480 0.000 1.609 1.933
state[me] 2.3697 0.160 14.805 0.000 2.055 2.685
state[mi] 1.9931 0.117 17.089 0.000 1.764 2.223
state[mn] 1.5804 0.094 16.880 0.000 1.396 1.765
state[mo] 2.1814 0.093 23.576 0.000 1.999 2.363
state[ms] 3.4486 0.209 16.472 0.000 3.036 3.861
state[mt] 3.1172 0.094 33.017 0.000 2.931 3.303
state[nc] 3.1872 0.252 12.661 0.000 2.692 3.683
state[nd] 1.8542 0.102 18.191 0.000 1.654 2.055
state[ne] 1.9555 0.106 18.534 0.000 1.748 2.163
state[nh] 2.2232 0.141 15.751 0.000 1.945 2.501
state[nj] 1.3719 0.073 18.709 0.000 1.228 1.516
state[nm] 3.9040 0.102 38.449 0.000 3.704 4.104
state[nv] 2.8769 0.081 35.492 0.000 2.717 3.036
state[ny] 1.2910 0.076 17.070 0.000 1.142 1.440
state[oh] 1.8032 0.102 17.691 0.000 1.603 2.004
state[ok] 2.9326 0.184 15.913 0.000 2.570 3.295
state[or] 2.3096 0.081 28.453 0.000 2.150 2.469
state[pa] 1.7102 0.086 19.776 0.000 1.540 1.880
state[ri] 1.2126 0.078 15.640 0.000 1.060 1.365
state[sc] 4.0348 0.355 11.372 0.000 3.336 4.733
state[sd] 2.4739 0.141 17.519 0.000 2.196 2.752
state[tn] 2.6020 0.092 28.398 0.000 2.422 2.782
state[tx] 2.5602 0.109 23.589 0.000 2.347 2.774
state[ut] 2.3137 0.155 14.972 0.000 2.010 2.618
state[va] 2.1874 0.147 14.917 0.000 1.899 2.476
state[vt] 2.5116 0.140 17.975 0.000 2.237 2.787
state[wa] 1.8181 0.082 22.084 0.000 1.656 1.980
state[wi] 1.7184 0.077 22.185 0.000 1.566 1.871
state[wv] 2.5809 0.108 23.971 0.000 2.369 2.793
state[wy] 3.2491 0.072 44.922 0.000 3.107 3.391
beertax -0.6559 0.188 -3.491 0.001 -1.026 -0.286
==============================================================================
'''
## entity-demeaned
Fatalities_demeaned = pd.DataFrame()
Fatalities_demeaned["fatal_rate"] = Fatalities["fatal_rate"]-Fatalities.groupby("state")["fatal_rate"].transform("mean")
Fatalities_demeaned["beertax"] = Fatalities["beertax"]-Fatalities.groupby("state")["beertax"].transform("mean")
smf.ols("fatal_rate~ beertax -1", data=Fatalities_demeaned).fit().summary()
'''
==============================================================================
coef std err t P>|t| [0.025 0.975]
------------------------------------------------------------------------------
beertax -0.6559 0.174 -3.772 0.000 -0.998 -0.314
==============================================================================
'''
위의 결과를 보면 추정된 계수(beertax)와 통계적 유의성이 동일함을 확인할 수 있습니다. t-statistic수치가 조금 상이하지만, 이것은 데이터를 처리하는 과정에서 발생한 것으로 볼 수 있을 정도로 미미합니다.
이번에는 Python에서 제공하는 Linearmodels 패키지를 활용하여 추정해보도록 하겠습니다.
from linearmodels import PanelOLS
## one-way fixed model
new_Fatalities = Fatalities.copy()
new_Fatalities=new_Fatalities.set_index(["state","year"])
mod = PanelOLS.from_formula('fatal_rate ~ beertax + EntityEffects', new_Fatalities )
res =mod.fit(cov_type = "clustered", cluster_entity=True)
print(res)
'''
==============================================================================
Parameter Std. Err. T-stat P-value Lower CI Upper CI
------------------------------------------------------------------------------
beertax -0.6559 0.2888 -2.2710 0.0239 -1.2243 -0.0874
==============================================================================
'''
## two-way fixed model
mod = PanelOLS.from_formula('fatal_rate ~ beertax + EntityEffects+TimeEffects', new_Fatalities )
res =mod.fit(cov_type = "clustered", cluster_entity=True, clsuter_time =True)
print(res)
'''
==============================================================================
Parameter Std. Err. T-stat P-value Lower CI Upper CI
------------------------------------------------------------------------------
beertax -0.6400 0.3823 -1.6740 0.0953 -1.3925 0.1126
==============================================================================
'''
PanelOLS 패키지를 이용할 때 cov_type = "clustered"로 주로 활용합니다. 이는 아래와 같이 그룹이 상이할 때 오차의 평균이 0이 아님을 가정하고 계수를 추정하는 것입니다.
'계량경제학' 카테고리의 다른 글
Binary 변수를 가지는 회귀분석(로짓 모형) (0) | 2020.11.02 |
---|---|
Binary 변수를 가지는 회귀분석(프로빗 모형) (2) | 2020.11.01 |
회귀분석의 해석 (0) | 2020.10.18 |
회귀분석 with interaction term (0) | 2020.10.12 |
비선형 회귀모형 > 다항 모형, Log 모형 (0) | 2020.10.04 |