선형 회귀는 매개변수가 없다. 매개변수가 없기 때문에 모델링을 할 때 매개변수 조정이 필요 없지만 그만큼 오버피팅되기 쉽다. 이러한 선형회귀의 과대적합 문제를 해결하기 위해서 규제를 사용한다.
규제 방법에는 L2규제인 릿지와 L1규제인 라쏘, 그리고 이 둘을 결합한 엘라스틱넷이 있다. 이번 포스팅에서는 라쏘와 엘라스틱넷에 대해 자세히 다뤄보겠다.
릿지와 마찬가지로 라쏘도 비용함수에 규제항을 더한다.
다만 L2노름의 제곱을 2로 나누는 릿지와 달리 계수의 절대값의 합인 L1노름을 패널티로 사용한다.
라쏘의 가장 중요한 특징은 덜 중요한 특성의 가중치를 제거하려고 하는 것이다. 즉, 어떤 계수는 가중치가 0이 되어서 아예 모델에 사용되지 않는 것이다.
from sklearn.linear_model import Lasso
from sklearn.datasets import load_breast_cancer
from sklearn.model_selection import train_test_split
import numpy as np
cancer = load_breast_cancer()
X_train, X_test, y_train, y_test = train_test_split(cancer.data, cancer.target, test_size=0.2, random_state=42)
lasso = Lasso().fit(X_train, y_train)
print('훈련세트 점수:{:.2f}'.format(lasso.score(X_train, y_train)))
print('테스트세트 점수:{:.2f}'.format(lasso.score(X_test, y_test)))
print('사용한 특성의 수:{}.'.format(np.sum(lasso.coef_ !=0))) #coef_ : 가중치/계수
>>>훈련세트 점수:0.55
>>>검증세트 점수:0.62
>>>사용한 특성의 수:3.
결과에서 알 수 있듯 라쏘는 훈련 세트와 테스트 세트 모두에서 결과가 그닥 좋지 않다. 또 load_breast_cancer 데이터의 feature는 30개인데 3개밖에 사용하지 않았다.
위에서는 알파를 기본값인 1로 훈련시켰지만 과소적합 방지를 위해 알파값을 줄여서 성능을 높일 수도 있다.
lasso1 = Lasso(alpha=0.01, max_iter=100000).fit(X_train, y_train)
print('훈련세트 점수:{:.2f}'.format(lasso1.score(X_train, y_train)))
print('테스트세트 점수:{:.2f}'.format(lasso1.score(X_test, y_test)))
print('사용한 특성의 수:{}.'.format(np.sum(lasso1.coef_ !=0)))
>>>훈련세트 점수:0.68
>>>테스트세트 점수:0.71
>>>사용한 특성의 수:8.
사용한 특성의 수도 전보다 늘었고 훈련세트, 테스트세트 점수도 소폭 개선되었다. 다만 알파 값을 너무 작게 하면 규제 효과가 사라지기 때문에 과대적합을 방지하기 어렵다.
from sklearn.linear_model import Ridge
ridge = Ridge(alpha=0.01, max_iter = 100000).fit(X_train, y_train)
print('훈련세트 점수:{:.2f}'.format(ridge.score(X_train, y_train)))
print('검증세트 점수:{:.2f}'.format(ridge.score(X_test, y_test)))
print('사용한 특성의 수:{}.'.format(np.sum(ridge.coef_ !=0)))
>>>훈련세트 점수:0.77
>>>검증세트 점수:0.75
>>>사용한 특성의 수:30.
동일한 데이터셋을 릿지에 적합시켜보면 릿지가 라쏘보다 성능이 더 좋으며 모든 특성을 훈련에 사용한다.
보통 릿지와 라쏘 중 릿지를 더 선호한다. 다만 특성이 엄청나게 많고 그중에서 극히 일부만 중요하다고 한다면 라쏘가 더 적합할 수 있다.
다음으로 엘라스틱넷은 라쏘와 릿지의 패널티를 절충한 모델이다.
규제항은 릿지와 회귀의 규제항을 단순 덧셈해서 사용하며 혼합 정도는 혼합비율인 r로 조절한다. r=0이면 릿지와 같고 r=1이면 라쏘와 같다.
from sklearn.linear_model import ElasticNet
ela = ElasticNet(alpha=0.01, l1_ratio = 0.5, max_iter = 100000).fit(X_train, y_train)
print('훈련세트 점수:{:.2f}'.format(ela.score(X_train, y_train)))
print('검증세트 점수:{:.2f}'.format(ela.score(X_test, y_test)))
print('사용한 특성의 수:{}.'.format(np.sum(ela.coef_ !=0)))
>>>훈련세트 점수:0.71
>>>검증세트 점수:0.73
>>>사용한 특성의 수:11.
혼합비율은 l1_ratio 파라미터로 조정한다. 0~1 사이의 값에서 조정하면 된다.
일반 선형회귀, 릿지, 라쏘, 엘라스틱넷 각각을 언제 사용하는게 좋을지 정리하자면 아래와 같다.
일반 선형 회귀 | 오버피팅이 발생하기 쉬우므로 일반적으로 피하는게 좋음 |
릿지 | 오버피팅 방지를 위한 가장 기본적인 규제 모델 |
라쏘 | 특성이 여러개이고 그 중 일부 특성만 필요한 경우 |
엘라스틱넷 | 특성 수가 훈련샘플 수보다 많거나 특성간 상관관계가 강한 경우 |
기본적으로는 릿지 모델을 가장 많이 사용하고, 특성이 많아서 일부만 필요한 경우에는 엘라스틱넷을 쓰는 것이 가장 좋다고 할 수 있다.
'파이썬 > 전처리' 카테고리의 다른 글
차원축소 방법 PCA 외 LDA, SVD 등 (0) | 2021.09.20 |
---|---|
파이썬 null 처리 방법, fillna()와 dropna()로 결측치 보정하기 (0) | 2021.07.17 |
베이지안 최적화(optimization) 개념 Auto Ml로 하이퍼파라미터 튜닝하기 (0) | 2021.07.12 |
원핫인코딩 파이썬 get_dummies 함수로 범주형 변수 전처리 (0) | 2021.07.10 |
데이터 스케일링 반드시 필요한 전처리 과정! fit_transform과 transform의 차이 (1) | 2021.06.23 |