다중공선성
공선성(collinearity): 하나의 독립변수가 다른 하나의 독립변수로 잘 예측되는 경우, 또는 서로 상관이 높은 경우
다중공선성(multicollinearity): 하나의 독립변수가 다른 여러 개의 독립변수들로 잘 예측되는 경우
(다중)공선성이 있으면:
- 계수 추정이 잘 되지 않거나 불안정해져서 데이터가 약간만 바뀌어도 추정치가 크게 달라질 수 있다
- 계수가 통계적으로 유의미하지 않은 것처럼 나올 수 있다
(다중)공선성의 진단
- 분산팽창계수(VIF, Variance Inflation Factor)를 구하여 판단
- 엄밀한 기준은 없으나 보통 10보다 크면 다중공선성이 있다고 판단(5를 기준으로 하기도 함)
예제 데이터
crab.csv를 다운로드 받아 연다. 이 데이터는 게의 크기와 무게 등을 측정한 데이터이다.
import pandas as pd
df = pd.read_csv('crab.csv')
df.head()
| crab | sat | y | weight | width | color | spine | |
|---|---|---|---|---|---|---|---|
| 0 | 1 | 8 | 1 | 3.05 | 28.3 | 2 | 3 |
| 1 | 2 | 0 | 0 | 1.55 | 22.5 | 3 | 3 |
| 2 | 3 | 9 | 1 | 2.30 | 26.0 | 1 | 1 |
| 3 | 4 | 0 | 0 | 2.10 | 24.8 | 3 | 3 |
| 4 | 5 | 4 | 1 | 2.60 | 26.0 | 3 | 3 |
회귀분석
from statsmodels.formula.api import ols
모형을 만든다.
model = ols('y ~ sat + weight + width', df)
모형을 적합시킨다.
res = model.fit()
분석 결과를 확인한다.
res.summary()
| Dep. Variable: | y | R-squared: | 0.514 |
|---|---|---|---|
| Model: | OLS | Adj. R-squared: | 0.506 |
| Method: | Least Squares | F-statistic: | 59.69 |
| Date: | Thu, 23 Jan 2020 | Prob (F-statistic): | 2.30e-26 |
| Time: | 16:11:28 | Log-Likelihood: | -55.831 |
| No. Observations: | 173 | AIC: | 119.7 |
| Df Residuals: | 169 | BIC: | 132.3 |
| Df Model: | 3 | ||
| Covariance Type: | nonrobust |
| coef | std err | t | P>|t| | [0.025 | 0.975] | |
|---|---|---|---|---|---|---|
| Intercept | -0.9366 | 0.500 | -1.872 | 0.063 | -1.924 | 0.051 |
| sat | 0.0971 | 0.009 | 11.018 | 0.000 | 0.080 | 0.115 |
| weight | -0.0465 | 0.098 | -0.475 | 0.635 | -0.240 | 0.147 |
| width | 0.0535 | 0.026 | 2.023 | 0.045 | 0.001 | 0.106 |
| Omnibus: | 29.724 | Durbin-Watson: | 1.475 |
|---|---|---|---|
| Prob(Omnibus): | 0.000 | Jarque-Bera (JB): | 7.545 |
| Skew: | 0.086 | Prob(JB): | 0.0230 |
| Kurtosis: | 1.992 | Cond. No. | 526. |
Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
결과를 보면 유의수준 5%에서 sat와 width는 통계적으로 유의미하고, weight는 유의미하지 않게 나왔다.
VIF 계산
statsmodels에서 variance_inflation_factor 함수를 불러들인다.
from statsmodels.stats.outliers_influence import variance_inflation_factor
모형식에서 독립변수는 절편, sat, weight, width 순이다.
model.exog_names
['Intercept', 'sat', 'weight', 'width']
X의 1번째 독립변수 sat의 VIF를 계산한다.
variance_inflation_factor(model.exog, 1)
1.15883687808578
X의 2번째 독립변수 weight의 VIF를 계산한다.
variance_inflation_factor(model.exog, 2)
4.8016794240392375
한 번에 모든 컬럼의 VIF를 계산한다.
pd.DataFrame({'컬럼': column, 'VIF': variance_inflation_factor(model.exog, i)}
for i, column in enumerate(model.exog_names)
if column != 'Intercept') # 절편의 VIF는 구하지 않는다.
| 컬럼 | VIF | |
|---|---|---|
| 0 | sat | 1.158837 |
| 1 | weight | 4.801679 |
| 2 | width | 4.688660 |
weight와 width의 VIF가 각각 4.8과 4.6이다. 게의 무게(weight)와 너비(width)는 서로 상관이 높기 때문에 VIF가 약간 높게 나타나는 것이다.
대처
- 계수가 통계적으로 유의미하지 않다면 대처
- 계수가 통계적으로 유의미하다면 VIF가 크더라도 특별히 대처할 필요없음
- 변수들을 더하거나 빼서 새로운 변수를 만든다
- (개념적으로나 이론적으로) 두 예측변수를 더하거나 빼더라도 문제가 없는 경우
- 예) 남편의 수입과 아내의 수입이 서로 상관이 높다면, 두 개를 더해 가족 수입이라는 하나의 변수로 투입한다
- 더하거나 빼기 어려운 경우는 변수를 모형에서 제거한다
- 단, 변수를 제거하는 것은 자료의 다양성을 해치고, 분석하려던 가설이나 이론에 영향을 미칠 수 있기 때문에 가급적 자제
weight와 width가 VIF 기준을 넘는 것은 아니지만 실험삼아 width를 제거해보자.
model = ols('y ~ sat + weight', df)
model.fit().summary()
| Dep. Variable: | y | R-squared: | 0.503 |
|---|---|---|---|
| Model: | OLS | Adj. R-squared: | 0.497 |
| Method: | Least Squares | F-statistic: | 85.93 |
| Date: | Thu, 23 Jan 2020 | Prob (F-statistic): | 1.63e-26 |
| Time: | 16:18:20 | Log-Likelihood: | -57.901 |
| No. Observations: | 173 | AIC: | 121.8 |
| Df Residuals: | 170 | BIC: | 131.3 |
| Df Model: | 2 | ||
| Covariance Type: | nonrobust |
| coef | std err | t | P>|t| | [0.025 | 0.975] | |
|---|---|---|---|---|---|---|
| Intercept | 0.0495 | 0.114 | 0.433 | 0.665 | -0.176 | 0.275 |
| sat | 0.0976 | 0.009 | 10.982 | 0.000 | 0.080 | 0.115 |
| weight | 0.1260 | 0.049 | 2.598 | 0.010 | 0.030 | 0.222 |
| Omnibus: | 40.033 | Durbin-Watson: | 1.433 |
|---|---|---|---|
| Prob(Omnibus): | 0.000 | Jarque-Bera (JB): | 8.709 |
| Skew: | 0.121 | Prob(JB): | 0.0128 |
| Kurtosis: | 1.928 | Cond. No. | 22.7 |
Warnings:
[1] Standard Errors assume that the covariance matrix of the errors is correctly specified.
이전의 분석에서는 weight가 유의미하지 않게 나왔지만, width를 제거한 후에는 유의미하게 나왔다. weight와 width가 공선성이 있기 때문에 width를 제거하자 weight가 유의미해진 것으로 볼 수 있다.