다중공선성(Multi Collinearity)
- **Multi-Collinearity(다중공선성)**는 독립 변수들 간의 강한 상관관계가 존재할 때 발생합니다. 즉, 한 독립 변수가 다른 독립 변수에 의해 설명될 수 있을 정도로 상관관계가 높은 상황을 의미합니다.
- 이 문제는 주로 회귀 분석에서 나타나며, 변수들 간의 관계를 해석하는 데 있어 큰 장애물이 될 수 있습니다.
- 일반적인 회귀식을 $Y=β_1X_1+β_2X_2+ϵ$로 표현할 수 있는데 다중공선성은 여기에서 $X_2=αX_1+ν$와 같은 관계가 있는 것을 의미합니다. 이런 경우, $X_1$과 $X_2$는 서로 독립적으로 영향을 미치는 것이 아니므로, $\beta_1$과 $\beta_2$를 개별적으로 추정하는 것이 불안정해지고, 결과적으로 각 변수의 실제 효과를 정확히 구분하기 어렵게 됩니다.
문제점
- 파라미터 추정의 불안정성: 다중공선성이 존재하면, 회귀 계수의 추정이 불안정해지고, 작은 데이터 변화에도 결과가 크게 달라질 수 있습니다.
- 해석의 어려움: 독립 변수들이 서로 상관관계를 가지면, 각 변수의 효과를 개별적으로 해석하는 것이 어려워집니다.
- 가설 검정의 신뢰도 저하: 다중공선성은 t-통계량을 왜곡시켜 가설 검정의 결과를 신뢰하기 어렵게 만듭니다.
Causal Inference시 영향도
- 독립 변수들 간의 높은 상관관계는 혼란 변수(confounder) 문제를 악화시켜, 실제로는 원인과 결과의 관계가 약하지만 혼란 변수 때문에 그 관계가 강해 보이게 만들 수 있기 때문입니다.
문제점
- 혼란 변수 문제: 인과 추론에서, 혼란 변수를 제대로 제어하지 못하면 잘못된 인과 관계를 추론할 수 있습니다. 다중공선성이 있으면 혼란 변수와 관련된 문제를 더 악화시킬 수 있습니다.
- 인과 효과의 왜곡: 다중공선성은 변수들 간의 상관관계를 강화하여 실제보다 더 큰 인과 효과를 나타내는 결과를 초래할 수 있습니다.
- 모델 해석의 어려움: 다중공선성이 존재하면 변수 간의 관계를 개별적으로 해석하기 어려워지기 때문에, 인과 추론에서 중요한 원인과 결과 간의 관계를 제대로 파악하지 못할 수 있습니다.
해결방안
- 변수 제거: 상관관계가 높은 변수를 제거하여 다중공선성을 줄일 수 있습니다. 하지만 이 방법은 중요한 변수를 놓칠 가능성이 있으므로 신중하게 사용해야 합니다.
- 정규화 회귀(Regularization): Lasso나 Ridge Regression과 같은 정규화 기법은 다중공선성을 줄이는 데 효과적입니다. 이 방법들은 계수의 크기를 제한함으로써 다중공선성을 완화할 수 있습니다.
- **4.3. 주성분 분석(PCA): 주성분 분석은 상관관계가 있는 변수들을 결합하여 새로운 독립 변수를 생성함으로써 다중공선성을 해결할 수 있습니다.
샘플 코드
- Ridge를 씀으로서 Coef(계수)가 바뀌는 것을 볼 수 있습니다.
- 이는 $X_1$과 $X_2$ 간의 강한 상관관계에서 발생하는 다중공선성을 완화시켜서 그렇습니다.
import numpy as np
import pandas as pd
import statsmodels.api as sm
import seaborn as sns
import matplotlib.pyplot as plt
from sklearn.linear_model import Ridge
from sklearn.preprocessing import StandardScaler
# 가상의 데이터 생성
np.random.seed(42)
n = 100
X1 = np.random.normal(size=n)
X2 = 2 * X1 + np.random.normal(size=n) # X1과 강한 상관관계를 가지는 X2
y = 3 * X1 + 2 * X2 + np.random.normal(size=n)
# 다중공선성 확인을 위한 상관계수 히트맵
data = pd.DataFrame({'X1': X1, 'X2': X2})
sns.heatmap(data.corr(), annot=True, cmap='coolwarm')
plt.title('Correlation Matrix')
plt.show()
# OLS 회귀 분석
X = sm.add_constant(data)
model = sm.OLS(y, X).fit()
print(model.summary())
# Ridge Regression (정규화 회귀)
scaler = StandardScaler()
X_scaled = scaler.fit_transform(data)
ridge_model = Ridge(alpha=1.0)
ridge_model.fit(X_scaled, y)
print(f"Ridge 회귀 계수: {ridge_model.coef_}")