다중공선성 예시
패키지 로딩
from statsmodels.datasets.longley import load_pandas # 통계관련 패키지
import pandas as pd
import seaborn as sns
import matplotlib.pyplot as plt
statsmodels 은 파이썬에서 통계 모델링을 위한 기능을 제공하는 라이브러리이며,
Longley 데이터셋은 공선성이 매우 높은 것으로 알려진 미국 거시경제 지표가 포함 되어있다.
load_pandas() 의 Dataset 객체 속성
- data: DataFrame 객체로 전체 데이터 반환
- endog : Series 객체로 종속변수 값 반환
- exog: DataFrame 객체로 독립변수 값 반환
변수 설명
독립변수 : GNPDFEL - GNP 디플레이터 / GNP - GNP (국민총생산) / UNEMP - 실업자구 / ARMED - 무장세력 규모 / POP - 인구 / YEAR - 연도
종속변수 : TOTEMP - 총 고용
data = load_pandas()
df = data.data # 결과값을 데이터프레임 객체로 받아옴
print(df.shape)
display(df.head())
다중공선성 multicollinearity
독립변수의 일부가 다른 독립 변수의 조합으로 표현될 수 있는 경우.
독립변수들이 서로 독립이 아니라 상호 상관관계가 강한 경우에 발생한다.
여부 판단 기준 : 독립변수 상관계수 r >= 0.9 or 각 변수의 분산팽창지수(VIF) >= 10
해결 방법:
- 다중공선성을 가지는 변수 중 하나를 제거(제거시 R^2가 유지되는 변수를 제거)
- VIF값이 가장 높은 독립변수를 하나씩 제거하여 모든 VIF 값이 10이하가 되도록 한다.
- PCA 이용한 변수 축소(독립변수가 많을수록 과적합 확률이 오르기 때문이다.)
- 정규화(가중치가 계속 커지는 걸 분리시키는)
독립변수와 종속변수 분리
data_x = data.exog
data_y = data.endog
독립변수간 상관관계 확인
회귀분석에서 독립변수들 사이에 선형관계가 존재하면 회귀계수의 정확한 추정이 어렵다.
우상향, 우하향 하는 모습 = 선형관계가 있다. (회귀계수 = 가중치)
sns.pairplot(data_x)
plt.show() # 상관관계 도표 확인 가능
data_x.corr() # 상관관계 계산해주는 함수
sns.heatmap : 상관관계의 수를 시각적으로 보여준다.
cmap = sns.light_palette('darkgray', as_cmap=True) # 히트맵의 디자인 요소
sns.heatmap(data_x.corr(), annot= True, cmap= cmap) # annot= True : 컬럼 이름 사용
plt.show()
다중공선성VIF(분산팽창지수) 값 확인
의존적인 독립변수를 선택하는 방법으로 VIF(Variance Inflation Factor) 를 사용할 수 있다.
from statsmodels.stats.outliers_influence import variance_inflation_factor
vif = pd.DataFrame()
vif['VIF'] = [ variance_inflation_factor(data_x.values, i) for i in range(data_x.shape[1])] # 전체 레코드(컬럼) 개수 만큼 돈다.
# 모든 컬럼에 대해서 VIF 값 계산하여 리스트로 반환
vif['Features'] = data_x.columns # 데이터 프레임에 컬럼값
vif
# 10이상이면 다중공선성에 문제가 생긴다.
독립변수 스케일링 후 VIF값 확인
: 각 독립 변수들 간의 변동폭이 큰 경우에는 표준화를 진행하면 훨씬 더 좋은 결과를 도출할 수 있다.
StandardScaler() : 표준화
from sklearn.preprocessing import StandardScaler
data_x_scaled = StandardScaler().fit_transform(data_x) # 표준화된 데이터가 담긴다.
vif = pd.DataFrame()
vif['VIF'] = [ variance_inflation_factor(data_x_scaled, i) for i in range(data_x.shape[1])] # 전체 레코드(컬럼) 개수 만큼 돈다.
# data_x_scaled : 넘파이 배열의 형태로 넘어온다.
vif['Features'] = data_x.columns # 데이터 프레임에 컬럼값
vif
변수제거
선형회귀분석(다중공선성 제거 전 모델 학습)
필요한 패키지 로드
from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
학습데이터와 평가데이터로 분할한다.(데이터의 양이 많지 않아, test 사이즈를 증가시켰다.)
x_train, x_test, y_train, y_test = train_test_split(data_x_scaled, data_y,
test_size= 0.4,random_state = 10) # 6:4 의 비율
모델 생성 후 학습(학습: fit())
model = LinearRegression()
model.fit(x_train,y_train)
6 개의 독립변수 모두 사용하여 결정계수 계산한다.
print(f'결정계수: {model.score(x_test,y_test):.3f}')
결정계수: 0.928
선형회귀분석(다중공선성 제거 후 모델 학습)
제거 대상 독립 변수 확인 (10 이상이라고 반드시 제거해야하는 것은 아니다.)
data_x_new = data_x[['GNPDEFL','UNEMP','ARMED']] # 상관관계 수치 중 상대적으로 낮은 것들을 임의로 뽑음
data_x_new.head()
스케일링(표준화), 데이터 분할
data_x_new_scaled = StandardScaler().fit_transform(data_x_new)
# 데이터 분할
x_train, x_test, y_train, y_test = train_test_split(data_x_new_scaled, data_y,
test_size= 0.4,random_state = 10) # 6:4 의 비율
모델 생성 후 학습, 결정계수 계산
model = LinearRegression()
model.fit(x_train,y_train)
print(f'결정계수: {model.score(x_test,y_test):.3f}') # 3개의 독립변수
# 다중공선성이 높은 변수를 지운다고해서 다 결정계수가 높아지는 것은 아니다.
결정계수: 0.954
과대적합 방지(데이터 규제)
규제: 데이터에 과적합을 방지하기 위한 방법 중 하나로 모델이 학습하는데 사용되는 가중치에 규제값을 주어 과적합이 되는 것을 막고, 모델의 일반화 성능을 증가시킨다 (모델의 일반화 = 약간의 오차를 허용하면서도 전체적인 데이터의 특성을 잘 반영하는 모델을 만드는 것을 말함)
결국 가중치의 모든 원소를 0과 가깝게 만드는 것이다.(y에 주는 영향을 최소화하여 편중을 막는 것)
규제 방법
벡터의 노름(norm) : 벡터를 기하학적으로 시각화하려 방향과 거리를 가진 화살표로 그렸을때, 벡터의 이동거리를 말한다.
- L1 노름은 벡터 성분의 절댓값을 모두 더하면된다. (맨하튼거리)
- L2 노름은 유클리드 거리로 구하면 된다.(피타고라스의 대각선 거리 구하는 공식 √(a^2+b^2)이다.)
1. L1 규제
손실함수에 가중치의 L1 노름과 상수 λ를 곱한 것이다. ( λ : 규제의 양조절)
L1 규제가 적용된 손실함수의 미분식은 아래와 같다.
- 절대값 w를 미분하면 양과 음의 부호만 남으므로 sin(w)로 표현한다.
- λ 를 이용해 규제의 양을 조절하는데 고정된 상수값(lambda)이 모든항에 대해 일괄적으로 빠지면서 자잘한 가중치들은 0으로 가버리고 중요한 가중치만 남아서 feature 의 수가 줄어드므로 과적합을 막게 된다
(VIF 변수제거와 유사하다.)
- λ 값을 낮추면 모델의 복잡도는 증가하여 학습모델에 대한 성능은 좋아질 수 있으나 규제의 효과가 사라져 과적합이 발생할 수 있다.
- 완전히 제외된다는 특성이 생긴다.
- L1 규제가 적용된 선형회귀 모델을 라쏘 (Lasso) 라고 한다.
w>0, 1
w = 0, 0
w <0, -1
2. L2 규제
손실함수에 가중치의 L2 노름과 상수 λ를 곱한값을 더한 것이다.
L2 규제가 적용된 손실함수의 미분식은 아래와 같다.
- 규제항들의 가중치는 모두 w로 미분되어서 결국 lambda*w 라는 일차항이 남게 된다.
각 가중치에 대해 비례하게 값이 빠지게 되어 다중선형 회귀모델 식의 가중치들은 완전히 0이 되지 않는다.
- L2 규제가 적용된 선형회귀 모델을 릿지 (Ridge) 라고 한다.
L1 규제 + L2 규제 = 엘라스틱 Elastic
'국비 교육 > 머신러닝, 딥러닝' 카테고리의 다른 글
[머신러닝] 회귀분석 - 교차검증 (0) | 2023.11.20 |
---|---|
[머신러닝] 회귀분석 - L1, L2규제 ((문제) 보스톤 집값 예측, 대한민국 육군 몸무게 예측) (0) | 2023.11.20 |
[머신러닝] 회귀분석 - 데이터 전처리(원핫 인코딩, 라벨 인코딩, 데이터 스케일링) (0) | 2023.11.20 |
[머신러닝] 지도학습 알고리즘 - 회귀 분석 Regression Analystic (0) | 2023.11.16 |