본문 바로가기
[업무 지식]/Statistics

[분산팽창요인] VIF(Variance Inflation Factor)

by 에디터 윤슬 2024. 11. 12.

VIF란

  • VIF는 다중 회귀 분석에서 다중공선성(Multicollinearity)을 진단하는 데 사용
  • 다중공선성이란 독립 변수들 간에 높은 상관관계가 있을 때 발생하는 문제로, 회귀 분석 결과의 신뢰성을 떨어뜨릴 수 있다
  • VIF는 각 독립 변수가 다른 독립 변수들에 의해 얼마나 설명되는지를 나타내며, 일반적으로 VIF 값이 10 이상이면 다중공선성 문제가 있다고 판단

파이썬 계산 방법

  • 필요한 라이브러리 설치 및 불러오기
  • variance_inflation_factor: VIF를 계산하는 함수.
  • add_constant: 상수항(절편)을 추가하는 함수.
import pandas as pd
from statsmodels.stats.outliers_influence import variance_inflation_factor
from statsmodels.tools.tools import add_constant

 

  • 데이터 준비
  • 'x'라는 독립변수들로 이루어진 데이터프레임
# 예시 데이터 생성
np.random.seed(0)
X = pd.DataFrame({
    'X1': np.random.rand(100),
    'X2': np.random.rand(100),
    'X3': np.random.rand(100)
})
  • VIF 계산 함수 정의
def calculate_vif(data):
    # 상수항 추가 (절편)
    data_with_constant = add_constant(data)

    # 각 변수에 대해 VIF 계산
    vif = pd.DataFrame()
    vif["Variable"] = data_with_constant.columns
    vif["VIF"] = [variance_inflation_factor(data_with_constant.values, i) for i in range(data_with_constant.shape[1])]

    return vif
  • VIF 계산 및 출력
# VIF 계산
vif_result = calculate_vif(X)
print(vif_result)
   Variable       VIF
0     const  1.005021
1        X1  1.035414
2        X2  1.030454
3        X3  1.016608

VIF 값 해석:
VIF = 1: 해당 독립 변수와 다른 독립 변수 간에 상관관계가 없음을 의미합니다.
1 < VIF < 5: 일반적으로 허용 가능한 범위로 간주됩니다.
VIF ≥ 10: 다중공선성 문제가 있을 가능성이 높습니다.

 

해결 방법 1 - 상관관계가 높은 변수 제거

  1. VIF 값을 계산하여 다중공선성이 있는 변수를 식별
  2. VIF 값이 높은 변수를 제거
import pandas as pd
from statsmodels.stats.outliers_influence import variance_inflation_factor
from statsmodels.tools.tools import add_constant

# VIF 계산 함수
def calculate_vif(data):
    data_with_constant = add_constant(data)
    vif = pd.DataFrame()
    vif["Variable"] = data_with_constant.columns
    vif["VIF"] = [variance_inflation_factor(data_with_constant.values, i) for i in range(data_with_constant.shape[1])]
    return vif

# 예시 데이터 생성
X = pd.DataFrame({
    'X1': [1, 2, 3, 4, 5],
    'X2': [2, 4, 6, 8, 10],  # X1과 완벽한 상관관계
    'X3': [5, 3, 4, 2, 1]
})

# VIF 계산 및 출력
vif_result = calculate_vif(X)
print(vif_result)

# X2와 X1이 매우 높은 상관관계를 보이면 X2를 제거
X_reduced = X.drop('X2', axis=1)

해결 방법 2 - 주성분분석(PCA)

  • 주성분분석(Principal Component Analysis)은 상관된 변수를 비상관된 주성분으로 변환하여 다중공선성을 해결할 수 있는 방법
  • 원래의 변수를 소수의 주성분으로 축소하여 사용

1. 필요한 라이브러리

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score

 

2. 예시 데이터 생성

# 예시 데이터 생성 (TV, Radio, Newspaper 광고비와 Sales)
data = {
    'TV': np.random.rand(100) * 100,
    'Radio': np.random.rand(100) * 50,
    'Newspaper': np.random.rand(100) * 30,
    'Sales': np.random.rand(100) * 100
}
df = pd.DataFrame(data)

# 독립 변수(X)와 종속 변수(y) 설정
X = df[['TV', 'Radio', 'Newspaper']]  # 독립 변수들
y = df['Sales']  # 종속 변수 (판매량)

 

3. 데이터 분할(훈련용/테스트용)

# 데이터를 훈련용과 테스트용으로 분할 (80% 훈련, 20% 테스트)
X_train, X_test, y_train, y_test = train_test_split(X, y, test_size=0.2, random_state=42)

 

4. 주성분분석(PCA) 적용

PCA를 적용하여 독립 변수들의 차원을 축소합니다. 여기서는 주성분을 2개로 설정하였습니다.

# PCA 객체 생성 (주성분을 두 개로 축소)
pca = PCA(n_components=2)

# 훈련 데이터에 PCA 적용 (차원 축소)
X_train_pca = pca.fit_transform(X_train)

# 테스트 데이터에도 동일한 변환 적용
X_test_pca = pca.transform(X_test)

# 주성분 설명력 확인 (각 주성분이 설명하는 분산 비율)
print("주성분 설명력:", pca.explained_variance_ratio_)

출력 예시:
주성분 설명력: [0.6978 0.2887]
첫 번째 주성분이 약 69.78%, 두 번째 주성분이 약 28.87%의 분산을 설명합니다.

 

5. 다중 회귀 분석 모델 학습

PCA로 변환된 데이터를 사용하여 다중 회귀 모델을 학습합니다.

# 다중 선형 회귀 모델 생성 및 훈련 (PCA 변환된 데이터를 사용)
model = LinearRegression()
model.fit(X_train_pca, y_train)

# 예측 수행 (테스트 데이터에 대해)
y_pred = model.predict(X_test_pca)

# 회귀 계수 및 절편 출력
print("회귀 계수:", model.coef_)
print("절편:", model.intercept_)

출력 예시:
회귀 계수: [0.1234 -0.5678]
절편: 50.1234

 

6. 모델 평가

# 모델 평가 (MSE와 R² 계산)
mse = mean_squared_error(y_test, y_pred)
r2 = r2_score(y_test, y_pred)

print("평균 제곱 오차(MSE):", mse)
print("결정 계수(R²):", r2)

출력 예시:
평균 제곱 오차(MSE): 892.1234
결정 계수(R²): -0.0123

 

7. 시각화

# PCA로 변환된 첫 번째 주성분과 두 번째 주성분에 대한 산점도 및 회귀선 시각화
plt.scatter(X_test_pca[:, 0], y_test, color='blue', label='Actual Sales')
plt.scatter(X_test_pca[:, 0], y_pred, color='red', label='Predicted Sales')
plt.plot(X_test_pca[:, 0], y_pred, color='red', linewidth=2)
plt.title('PCA + Linear Regression')
plt.xlabel('First Principal Component')
plt.ylabel('Sales')
plt.legend()
plt.show()