#10. 선형 모델, 선형 회귀, 릿지 회귀, 라쏘 회귀, 복잡도 제어
* 본 글은 '파이썬 라이브러리를 활용한 머신러닝(안드레아스 뮐러, 세라 가이도 지음, 한빛미디어)'2장과
'비즈니스를 위한 데이터 과학(포스터 프로보스트, 톰 포셋 지음, 한빛미디어) 5장을 참고해 작성되었습니다.
*내용에 오류가 있을 수 있습니다.
1. 선형 회귀 Intro ¶
선형 회귀 모델에 대한 일반적인 예측 함수는 아래와 같다.
$\hat{y} = w[0]x[0]+w[1]x[1]+...+w[p]x[p]+b$
- $x[0], x[1], ... x[p]$는 각각의 데이터 포인트에 대한 특성
- $w[0], w[1], ...w[p]$와 $b$는 모델이 학습할 파라미터
- $\hat{y}$는 모델이 산출하는 예측값
직선의 방정식 개념에 대입해서 생각하면, $w[0], w[1], ...w[p]$는 각각의 특성($x$)에 대한 기울기이다.
각각의 특성마다 기울기의 값이 생성된다. 이는 가중치의 의미를 가지며, 결과적으로 예측값은 특성들의 가중치($w$, 기울기)를 곱한 합으로 표현된다.
특성의 개수에 따라 선형 회귀 모델의 모양이 다르다. 1개일때는 직선, 2개일때는 평면, 3개부터는 초평면의 형태이다.
import numpy as np
import matplotlib.pyplot as plt
import mglearn
#wave데이터셋으로 확인해보자
mglearn.plots.plot_linear_regression_wave()
#w[0]의 값은 선형 모델의 기울기를 의미하며, b는 그래프의 y절편의 값과 같다.
#특성이 하나일 때는 선형 모델은 직선의 모양이다.
w[0]: 0.393906 b: -0.031804
위와 같이 1개의 특성을 사용한 직선 형태의 회귀 모델은 데이터를 예측하는 데 제약이 많이 따른다.
융통성이 적어 훈련 데이터를 충분히 반영하지 못하며, 그 때문에 high bias, low variance의 결과가 나온다. (#9의 글을 참조하자)
따라서 융통성 있는 모델을 만들기 위해서는 보다 많은 특성을 사용해야 한다.
보다 많은 특성을 포함하는 선형 회귀 모델에는 여러 종류가 있다. 각각의 모델마다 파라미터 학습 방법과 복잡도 제어 방법이 다르다.
(복잡도는 특성을 포함하면 할 수록 증가한다. 보다 자세한 내용은 이전 글 #9를 참조하자.)
2. 선형 회귀 Linear Regression (최소제곱법 Ordinary Least Squares, OLS)¶
선형 회귀는 예측한 타깃값과 훈련 데이터 세트에 있는 타깃값 사이의 평균제곱오차를 최소화하는 파라미터($w, b$)를 찾는 알고리즘이다.
평균제곱오차는 예측값과 타깃값의 차를 제곱해서 모두 더한 후 샘플의 개수로 나눠서 계산한다.
$\frac{1}{n}\sum_{i=1}^n (y_i - \hat{y_i})^2 $
이전에 공부했던 최근접 이웃 알고리즘에서 KNeighborsRegression, KNeighborsClassifier의 매개변수는 n_neighbors이었다.
우리는 이 매개변수를 통해서 이웃의 개수를 설정했고, 이웃의 개수에 따라 모델의 복잡도가 달라졌다.
이는 곧 이웃의 개수를 통해 복잡도를 제어했다는 말과 같다.
그러나 선형 모델에서는 매개변수가 없다. 따라서 모델의 복잡도를 제어할 수 있는 방법 또한 없다.
2.1 wave 데이터셋의 선형 모델¶
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
#샘플 개수가 60개인 wave데이터셋 만들기
X, y = mglearn.datasets.make_wave(n_samples = 60)
#훈련 세트와 시험 세트로 나누기
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state = 42)
#선형 회귀 알고리즘을 표현하는 lr객체를 생성, 훈련 데이터로 모델 학습시키기
lr = LinearRegression().fit(X_train, y_train)
#파라미터 값 출력하기
print("(기울기 파라미터)lr.coef_: {}".format(lr.coef_))
print("(편향 파라미터)lr.intercept_: {}".format(lr.intercept_))
lr객체의 coef_속성에는 기울기 파라미터(가중치weight, 또는 계수coefficient)w의 값이 저장되어 있다.
lr객체의 intercept_에는 절편intercept(또는 편향offset)파라미터 b의 값이 저장되어 있다.
scikit-learn에서 훈련 데이터로부터 유도된 속성은 항상 끝에 _를 붙인다. 이는 사용자 지정 매개변수와 구분하기 위함이다.
(기울기 파라미터)lr.coef_: [0.39390555]
(편향 파라미터)lr.intercept_: -0.03180434302675976
intercept_속성은 항상 실수float값 하나이지만 가중치 파라미터인 coef_속성은 각각의 입력된 특성($x$)에 대응되는 Numpy배열이다.
2.2 특성 개수에 따른 모델 성능 확인하기-과소적합과 과적합¶
#특성이 1개인 데이터셋의 훈련 세트와 시험 세트의 성능 확인하기_과소적합
print("훈련 세트 점수: {:.2f}".format(lr.score(X_train, y_train)))
print("시험 세트 점수: {:.2f}".format(lr.score(X_test, y_test)))
훈련 세트 점수: 0.67
시험 세트 점수: 0.66
시험 세트 점수가 0.66으로, 성능이 만족스럽지 못하다. 그 대신 훈련 세트와 시험 세트의 정확도 수준(성능)은 비슷한 것을 알 수 있다.
이전 글에서도 알아보았지만, 모델의 복잡도가 높지 않을때는(특성의 개수가 적을 때는) 훈련과 시험 세트의 오류율 수준에 괴리는 거의 없다.
이처럼 모델의 복잡도가 너무 낮으면 과소적합의 현상이 발생한다. 너무 단순해서 제대로 예측을 수행하지 못하는 것이다.
#특성이 여러개인 데이터셋의 훈련 세트와 시험 세트의 성능 확인하기_과적합
보스턴 주택가격 데이터셋은 윤리적 문제로 인해 지양하라고 해서(...)
마크다운으로 코드만 표시하고 실습결과는 비공개로 하려고 한다.
대안은 없나, csv파일 없나, 캘리포니아 데이터셋을 사용할 순 없나 별 방법을 다 시도해보았는데
나의 부족한 지식으로 인해 해결하지 못했다.
데이터 구조 공부를 해야하겠다는 생각이 들었다. 스스로 너무 무지렁이 같아서..ㅋㅋ
#보스턴 주택 데이터셋 불러오기
X, y = mglearn.datasets.load_extended_boston
#확장된 보스턴 집값 데이터셋 훈련-시험 데이터셋으로 나누기
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state = 0)
#알고리즘 객체 lr생성하기
lr = LinearRegression().fit(X_train, y_train)
#데이터셋 별 점수 확인하기
print("훈련 세트 점수: {:.2f}".format(lr.score(X_train, y_train)))
print("시험 세트 점수: {:.2f}".format(lr.score(X_test, y_test)))
Out:
훈련 세트 점수: 0.95
시험 세트 점수: 0.61
훈련 세트 점수는 0.95로 높지만 시험 세트 점수는 0.61로 큰 차이를 보인다.
이는 훈련 데이터에만 모델이 최적화되어 있어 시험 데이터에는 일반화에 실패했기 때문이다.
이러한 성능의 괴리는 과적합 신호로 해석되며, 복잡도를 제어할 수 있는 모델을 사용해서 일반화해야 한다.
앞서 선형 회귀에는 매개변수가 없어 복잡도를 제어할 수 없다고 했다.
그러므로 우리는 기본 선형 회귀 모델 말고 다른 모델을 알아보아야 한다.
결론: 기본 선형 회귀 모델은 특성의 개수가 많아질수록 생기는 과적합 문제를 해결할 수 없다. 따라서 다른 선형 회귀 모델을 사용해야 한다!
3. 릿지 회귀 Ridge Regression¶
과적합 문제를 해결한다는 것은 특성이 늘어남에 따라 생기는 복잡도를 제어한다는 뜻이다.
과적합된 모델은 low bias(훈련 데이터에만 최적화됨. 모델이 훈련 데이터 전부를 완전히 암기해버린 상태),
high variance(새로운 데이터에 추가되면 모델이 그에 따라 심하게 변형됨. 모든 데이터에 민감하게 반응)의 상태를 가지게 된다.
릿지 회귀는 과적합을 막기 위해 편향bias를 조금 높이고 분산variance를 낮추어 복잡도를 제어한다.
이러한 정규화-모델의 파라미터 값을 제어해 과적합을 줄이고 일반화 성능을 높이는 방식-기법을 사용하는 모델이 릿지 회귀 모델이다.
간단하게 말하자면 선형 회귀 방정식에서 볼 수 있는 가중치$w$의 절댓값을 0에 가깝게 만들고자 하는 것이다.
이처럼 특성의 파라미터값(기울기)을 줄여 특성들이 가지는 영향력을 최소한으로 만드는 것을 '규제Regularization'이라고 부른다.
릿지 회귀에서 사용되는 규제는 L2규제라고 한다.
3.1 릿지 회귀 구현하기¶
#아래 코드는 위에 등장한 보스턴 주택 데이터셋을 사용한 것
#linear_model.Ridge 불러오기
from sklearn.linear_model import Ridge
#객체 생성하고 훈련 데이터로 모델 학습하기
#객체를 생성할 때는 Ridge()의 매개변수 alpha를 입력하는데, 입력하지 않으면 기본값인 alpha = 1.0이 입력된다.
ridge = Ridge().fit(X_train, y_train)
print("훈련 세트 점수: {:.2f}".format(ridge.score(X_train, y_train)))
print("시험 세트 점수: {:.2f}".format(ridge.score(X_train, y_train)))
#Out:
훈련 세트 점수: 0.89
시험 세트 점수: 0.75
결과를 보면 일반 선형 회귀에서의 점수보다(0.95, 0.61, 점수 간 괴리 0.34) 괴리가 줄어든 것을 확인할 수 있다.
이처럼 릿지 회귀는 선형 회귀보다 덜 자유로운 모델이기 때문에 과적합 정도가 더 작다.
따라서 릿지 회귀는 복잡도가 낮아짐에 따라 선형 회귀 모델보다 상대적으로 낮은 성능, 높은 일반화 수준을 가진 모델이다.
alpha는 훈련 세트 성능 대비 모델 단순화 정도를 결정하는 매개변수다. 값이 높을수록 파라미터 값은 0에 가깝다. (제약이 높아짐) 반대로 알파 값이 낮을수록 제약이 낮아져, 계속 값을 줄이다보면 일반적인 선형회귀 모델과 거의 비슷한 형태가 되어버린다.
#alpha = 10일때
ridge = Ridge(alpha = 10).fit(X_train, y_train)
print("훈련 세트 점수: {:.2f}".format(ridge.score(X_train, y_train)))
print("시험 세트 점수: {:.2f}".format(ridge.score(X_train, y_train)))
#Out:
훈련 세트 점수: 0.79
시험 세트 점수: 0.64
#alpha=0.1일때
ridge = Ridge(alpha = 0.1).fit(X_train, y_train)
print("훈련 세트 점수: {:.2f}".format(ridge.score(X_train, y_train)))
print("시험 세트 점수: {:.2f}".format(ridge.score(X_train, y_train)))
#Out:
훈련 세트 점수: 0.93
시험 세트 점수: 0.77
데이터셋에 따라 최적의 alpha값은 다르다.
alpha값이 커질수록 파라미터 제약이 커져 복잡도와 융통성이 줄어든다. 대신 일반화 성능이 좋아진다.
aplha값이 작아질수록 제약이 줄어 모델의 자유도가 상승해 복잡도가 올라가 모델의 융통성이 커진다. 반면에 일반화 성능은 줄어든다.
따라서 여러 alpha값을 대입해 최적의 규제 수준을 찾아내면 된다. (테스트 세트에 대한 성능이 높아질때까지 알파값을 줄여보면 된다.)
위의 데이터셋에서는 alpha = 0.1일때 가장 좋은 성능을 보여주었다.alpha값은 변수 파라미터를 제어하는 매개변수라고 했다. alpha값이 커지면 coef_의 절댓값이 크기는 작아진다.
3.2 릿지 회귀와 선형 회귀 비교하기¶
- 릿지에는 규제가 있어 훈련 데이터 점수는 선형 회귀가 릿지 회귀보다 전반적으로 높다.
- 시험 데이터 점수는 릿지 회귀의 것이 선형 회귀보다 더 높다. 이는 데이터셋의 크기가 작을수록 부각된다.
- 다만 데이터셋의 크기가 충분히 커지면 규제의 영향력이 줄어들어 두 모델의 성능이 서로 비슷해진다.
- 선형 회귀의 훈련 데이터 성능은 데이터셋의 크기가 커질수록 줄어든다. 데이터의 크기가 커지면 훈련 데이터 암기 부담도 커지기 때문이다.
4. 라쏘 회귀 Lasso Regression¶
선형 회귀를 규제하는 다른 방법으로는 라쏘Lasso가 있다.
라쏘 또한 계수의 값을 0에 가깝게 만들고자 하는데, 방법이 조금 달라 L1규제라고 부른다.
라쏘 규제를 사용하면 아예 0이 되는 계수가 발생하기도 한다. 즉, 예측에서 완전히 제외되는 특성이 생긴다는 뜻이다.
특성 선택feature selection이 이뤄진다고 할 수 있으며, 일부 특성이 제외되면 모델의 중요한 특성이 무엇인지 확인할 수 있게 된다.
라쏘 회귀 또한 릿지 회귀와 같이 alpha 매개변수를 통해 복잡도를 제어한다.
alpha = 1.0이 기본값이며, 값이 커질수록 사용되는 특성의 수가 줄어들어 과소적합에 가까워진다.
alpha값이 작아지면 계수에 대한 제약이 줄어들어 모델의 복잡도는 증가하고, 성능은 보다 나아진다. 그러나 과대적합 위험에 가까워진다.
엘라스틱넷(Elastic-Net)방식에 대해서도 알아야 라쏘에 대해 더 잘 이해할 수 있지만, 이번에는 이 정도까지만 알아보고자 한다.
엘라스틱넷은 L1, L2규제를 함께 사용하는 방식으로 각각의 규제에서 사용될 매개변수 2개를 모두 조정해야 한다.
'배우는 것 > Maching Learning' 카테고리의 다른 글
#12. 결정 트리, 특성중요도, 결정 트리 앙상블, 부트스트랩 샘플링 (0) | 2021.12.29 |
---|---|
# 11. 이진 분류, 선형 분류 모델, 로지스틱 회귀, 지원 벡터 기계 (0) | 2021.12.28 |
#9. 과적합, 과소적합, 일반화, 이전 글에 대한 배경지식 확장 (0) | 2021.12.27 |
#8. 최근접 이웃 알고리즘 실습, 이웃의 개수가 지도학습에 미치는 영향 (0) | 2021.12.27 |
#7. 파이썬 기본지식 공부(2)_스칼라형, 튜플, 리스트, 사전 (0) | 2021.12.23 |