다중공선성
공선성(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
가 유의미해진 것으로 볼 수 있다.