머신러닝 알고리즘 첫 번째로 선형회귀 알고리즘을 공부하면서 지난 글에서 하나의 독립변수와 하나의 종속변수의 선형관계를 나타내는 단순 선형회귀, 여러 개 독립변수와 하나의 종속변수의 선형관계를 나타내는 다중 선형회귀에 대해 알아보았다.
캐글이나 실제 머신러닝 모델링 프로젝트를 하면 막상 선형 회귀나 로지스틱 회귀와 같은 회귀 알고리즘의 성능이 다른 알고리즘 대비 떨어지는 경우가 많은데, 데이터에 선을 그어 간단히 값을 예측하거나 분류할 수 있는 알고리즘 같지만 막상 사용하려면 신경써야할 게 많이 때문이다.
선형 회귀분석의 가정과 다중공선성
선형회귀는 기본적으로 4가지 사항을 전제로 하는데 독립변수에 따른 종속변수가 선형성을 띄어야 하고, 종속변수의 분산이 동일하고 정규분포를 이뤄야 하며, 마지막으로 독립변수들이 서로 간에 독립성을 띄어야 한다는 것이다. 이 4가지가 만족되지 않으면 제대로 된 회귀식이 나오리라 기대하기 어렵다.
데이터 분석 시 예측 대상이 되는 종속변수의 값이나 분포 상의 특징 같은 것은 기본적으로 확인하지만, 처음으로 다중공선성에 대해 신경 써본 건 금융사기 거래를 예측하는 IEEE-CIS Fraud Detection라는 캐글 데이터를 가지고 연습할 때였다. 컬럼이 무려 400개에 달했는데, 서로 상관관계가 높은 컬럼들이 많아 보였다. 컬럼이 너무 많아서 그룹별로 묶어 다중공선성을 찾아 열심히 제거한 기억이 있는데 결론적으로는 다중공선성이 있어도 큰 상관없는 Decision Tree 계열의 알고리즘들의 결과가 좋았다.
다중공선성(Multicollinearity)이란 종속변수와 독립변수가 아니라 독립변수들간에 상관관계가 강할 때각 변수들이 종속변수에 어느 정도 영향을 미치는 지 정확히 알 수 없다는 문제이다. 단순 선형회귀는 상관없지만, 독립변수가 여러 개인 다중 선형회귀 모델을 사용하고자 한다면 다중공선성을 신경써야 할 것이다.
다중공선성을 판단하는 방법
그렇다면 컬럼들 간에 다중공선성이 존재하는 지 어떻게 알까? 캐글에서 대표적인 회귀 문제인 집값 예측 문제를 가지고 다중공선성이 있는 경우와 제거한 경우의 모델 성능을 비교해 보도록 하자. 참고로 해당 데이터셋은 위치, 크기, 주자창 수용능력, 주차장 크기 등의 80 개 변수를 가지고 집값을 예측하는 문제이다.
다중공선성을 그대로 둔 경우는 기본 데이터셋에서 결측치를 임의의 값으로 채우고 텍스트 컬럼의 인코딩만 완료해서 선형 회귀모델의 기본 성능을 확인했다.
베이스라인 성능
다중공선성을 제거한 경우는 위에서 적용한 기본 베이스라인에 히트맵과 VIF 라이브러리를 사용해 다중공선성이 높은 컬럼들을 제거한 경우다. 우선 씨본 라이브러리의 히트맵이나 Pairplot 등을 사용해 변수 간의 관계를 시각화할 수 있다.
히트맵(Heatmap)은 색의 정도를 이용해 데이터 간의 상관관계를 나타내는 시각화 기법으로, corr() 함수를 이용해 상관관계 지수를 계산한 테이블 값을 히트맵의 인풋으로 넣으면 각 변수들간의 일대일 상관관계를 시각적으로 확인할 수 있다.
해당 데이터의 경우 컬럼 수가 워낙 많아서 그냥 히트맵을 그린다면 80개 변수와 그에 대응하는 80개 변수의 상관관계를 파악하기 힘들 것 같아 의미상 비슷한 컬럼들이 묶여질 수 있게 임의로 컬럼을 6개의 그룹으로 나눠 히트맵을 6개로 나눠 확인했다.
다음으로 statsmodels의 VIF (Variance Inflation Factor) 함수를 이용해 다중공선성을 계산했다. VIF (Variance Inflation Factor)는 하나의 독립변수를 다른 독립변수들로 선형회귀한 성능을 나타낸 것으로 즉, 독립변수를 하나씩 돌아가며 종속변수로 만들어 나머지 변수들과 회귀식과 R2를 구해 해당 변수의 VIF 지수를 구하는 것이다. 종속변수와 나머지 변수들간의 상관관계가 크다면 그 회귀식의 R2가 높게 나와 VIF 지수가 팽창되는 구조로 되어 있다. 보통 VIF 값이 10보다 크면 다중공선성이 크다고 판단한다.
변수 i에 대한 VIF지수
statsmodels의 VIF 함수를 사용하면 그 값을 일일이 하나씩 계산할 필요없이 변수들을 돌아가면서 VIF 지수를 계산한 결과값을 리턴한다.
해당 데이터셋에서도 원래 예측해야 하는 종속변수SalePrice까지 포함해 총 81개 항목의 VIF 지수를 계산한 결과 49개의 컬럼의 VIF값이 10보다 컸다. 당연히 예측 대상인 SalePrice는 제거대상이 아니다.
10보다 크다고 모두 제거할 것이 아니라 자세히 값들을 살펴보면 마치 짝꿍을 이루듯 비슷한 값들이 연속적으로 크게 나오는 값들이 있다. 이 때 둘 중의 하나를 제거하면 되는데 나 같은 경우는 VIF 지수를 기본으로 제거하되 히트맵의 상관관계 지수를 참고해 혹시 둘 중에 다른 변수들과의 상관관계도 높은 변수가 있다면 해당 변수를 제거하는 방식으로 히트맵을 고려했다.
결과적으로 VIF 지수가 높은 22개의 컬럼을 드롭했으며, 다시 선형회귀 모델의 성능을 확인한 결과 트레인과 테스트 셋 간의 오버피팅이 해소되었으며, 테스트 셋의 성능이 0.67에서 0.73으로 향상 되었다. 여기에 EDA를 통해 좀더 의미있는 값들로 결측치를 채우고 이상치 처리를 하고 피처 엔지니어링 등을 추가한다면 성능 향상을 꾀해볼 수 있을 것이다.
이 글에서는 다중공선성 문제가 의심되는 변수를 제거하는 방식으로 해결을 했는데 그 외에도 PCA 분석이나 t-SNE와 같은 비지도학습 알고리즘을 통해 변수들의 차원을 새로운 차원으로 축소해 다중공선성 문제를 해결하는 방법 등도 있다.