2023. 8. 8. 09:20ㆍ2023-2 KHUDA/ML 기초세션
이 게시물은 한빛미디어의 <혼자 공부하는 머신러닝 + 딥러닝>를 정리한 글입니다.
혼자 공부하는 머신러닝+딥러닝
혼자 공부하는 머신러닝 딥러닝, 무료 동영상 강의, 머신러닝+딥러닝 용어집을 다운로드 하세요. 포기하지 마세요! 독학으로 충분히 하실 수 있습니다. ‘때론 혼자, 때론 같이’ 하며 힘이 되겠
hongong.hanbit.co.kr
다중 회귀
Chapter3-2 에서는 하나의 특성을 사용해 선형 회귀 모델을 훈련시켰다. 여러 개의 특성을 사용한 선형 회귀를 다중 회귀라 한다. 1개의 특성을 사용하면 선형 회귀 모델은 직선을 학습한다. 2개의 특성을 사용하면 선형 회귀는 3차원 공간에서 평면을 학습한다.
이번 예제에서는 농어의 높이와 두께를 제곱하여 추가한다. 여기에 각 특성을 서로 곱해 또 다른 특성을 만들어준다. 예를 들어 농어 길이 x 농어 높이를 새로운 특성으로 만들어준다. 이렇게 기존의 특성을 사용해 새로운 특성을 만들어내는 작업을 특성 공학(feature engineering)이라 한다.
데이터 준비
판다스(pandas)는 유명한 데이터 분석 라이브러리이다. 데이터프레임(dataframe)은 판다스의 핵심 데이터 구조이다. 넘파이 배열과 비슷하게 다차원 배열을 다룰 수 있지만 훨씬 더 많은 기능을 제공한다. 또한 데이터프레임은 넘파이로 쉽게 바꿀 수 있다.
인터넷에서 데이터를 바로 다운로드하여 사용한다.(편하다!)
import pandas as pd
df = pd.read_csv('https://bit.ly/perch_csv')
perch_full = df.to_numpy()
#to_numpy -> numpy배열로 바꿔줌
print(perch_full)
타깃 데이터는 이전과 동일하게 준비한다.
import numpy as np
#weight가 target이 된다.
perch_weight = np.array(
[5.9, 32.0, 40.0, 51.5, 70.0, 100.0, 78.0, 80.0, 85.0, 85.0, 110.0,
115.0, 125.0, 130.0, 120.0, 120.0, 130.0, 135.0, 110.0, 130.0,
150.0, 145.0, 150.0, 170.0, 225.0, 145.0, 188.0, 180.0, 197.0,
218.0, 300.0, 260.0, 265.0, 250.0, 250.0, 300.0, 320.0, 514.0,
556.0, 840.0, 685.0, 700.0, 700.0, 690.0, 900.0, 650.0, 820.0,
850.0, 900.0, 1015.0, 820.0, 1100.0, 1000.0, 1100.0, 1000.0,
1000.0]
)
from sklearn.model_selection import train_test_split
train_input, test_input, train_target, test_target = train_test_split(
perch_full, perch_weight, random_state=42)
사이킷런의 변환기
변환기(transformer) - 사이킷런에 있는 특성을 만들거나 전처리하기 위한 다양한 클래스
PolynomialFeatures를 사용해 특성을 늘려준다.
from sklearn.preprocessing import PolynomialFeatures
#degree=2
poly = PolynomialFeatures(include_bias=False)
poly.fit([[2, 3]])
#1(bias)(include_bias=False로 삭제됨),
#2, 3, 2**2, 2*3, 3**2
print(poly.transform([[2, 3]]))
절편을 위한 항이 제거되고 특성의 제곱과 특성끼리 곱한 항만 추가되었다.
이제 이 방식으로 train_poly와 test_poly데이터를 만든다.
poly = PolynomialFeatures(include_bias=False)
poly.fit(train_input)
train_poly = poly.transform(train_input) #2차원이였던 샘플이 9차원으로 바뀜
print(train_poly.shape)
#-> (42, 9) sample은 42개, 9차원
test_poly = poly.transform(test_input)
다중 회귀 모델 훈련하기
LinearRegression으로 train_poly를 사용해 모델을 훈련한다.
from sklearn.linear_model import LinearRegression
lr = LinearRegression()
lr.fit(train_poly, train_target)
print(lr.score(train_poly, train_target))
# -> 0.9903183436982125
print(lr.score(test_poly, test_target))
# -> 0.9714559911594111
테스트 세트에 대한 점수는 높아지지 않았지만, 과소적합 문제는 더 이상 나타나지 않는다.
그렇다면 특성을 더 많이 추가해 학습해보겠다.
poly = PolynomialFeatures(degree=5, include_bias=False)
poly.fit(train_input)
train_poly = poly.transform(train_input)
test_poly = poly.transform(test_input)
print(train_poly.shape)
# -> (42, 55)
lr.fit(train_poly, train_target)
print(lr.score(train_poly, train_target))
# -> 0.9999999999996433
print(lr.score(test_poly, test_target))
# -> -144.40579436844948
테스트 성능이 음수를 나타낸다. 특성의 개수를 크게 늘리면 선형 모델이 훈련 세트에 대해 거의 완벽하게 학습해 테스트 점수가 좋지 않다.
규제
규제(regularization)는 머신러닝 모델이 훈련 세트를 과도하게 학습하지 못하도록 방해하는 것이다. 즉 과대적합을 막는다. 선형 회귀 모델의 경우, 특성에 곱해지는 개수(또는 기울기)의 크기를 작게 만들어준다.
앞서 55개의 특성으로 훈련한 선형 회귀 모델의 계수를 규제하여 훈련 세트의 점수를 낮추고 대신 테스트 세트의 점수를 높여준다.
Chapter2에서 보았듯이 특성의 스케일이 정규화되지 않으면, 여기에 곱해지는 계수 값도 차이 나게 된다.
따라서 StandardScaler 클래스를 이용해 규제 전, 표준화를 해준다.
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
ss.fit(train_poly)
train_scaled = ss.transform(train_poly)
test_scaled = ss.transform(test_poly)
선형 회귀 모델에 규제를 추가한 모델을 릿지(ridge)와 라쏘(lasso)라 부른다. 릿지는 계수를 제곱한 값을 기준으로 규제를 적용하고, 라쏘는 계수의 절댓값을 기준으로 규제를 적용한다. 일반적으로는 릿지를 조금 더 선호한다. 두 알고리즘 모두 계수의 크기를 줄이지만 라쏘는 아예 0으로 만들 수도 있다.
릿지 회귀
앞서 준비한 train_scaled 데이터로 릿지 모델을 훈련한다.
from sklearn.linear_model import Ridge
ridge = Ridge()
ridge.fit(train_scaled, train_target)
print(ridge.score(train_scaled, train_target))
# -> 0.9896101671037343
print(ridge.score(test_scaled, test_target))
# -> 0.9790693977615387
확실히 많은 특성을 사용했음에도, 좋은 성능을 내고 있다.
릿지와 라쏘 모델을 사용할 때, 규제의 양을 임의로 조절할 수 있다. 모델 객체를 만들 때 alpha 매개변수로 규제의 강도를 조절한다. alpha 값이 크면 규제 강도가 세지므로 계수 값을 더 줄이고 조금 더 과소적합 되도록 유도한다. alpha 값이 작으면 계수를 줄이는 역할이 줄어들고 선형 회귀 모델과 유사해지므로 과대적합될 가능성이 크다.
적절한 alpha 값을 찾으려면 alpha값에 대한 결정계수의 그래프를 그리면 된다.

import matplotlib.pyplot as plt
alpha_list = [0.001, 0.01, 0.1, 1, 10, 100]
train_score = []
test_score = []
for alpha in alpha_list:
#릿지 모델을 만듭니다
ridge = Ridge(alpha=alpha)
#릿지 모델을 훈련합니다.
ridge.fit(train_scaled, train_target)
#훈련 점수와 테스트 점수를 저장합니다.
train_score.append(ridge.score(train_scaled, train_target))
test_score.append(ridge.score(test_scaled, test_target))
plt.plot(np.log10(alpha_list), train_score)
plt.plot(np.log10(alpha_list), test_score)
plt.xlabel('alpha')
plt.ylabel('R^2')
plt.show
위는 훈련 세트 그래프, 아래는 테스트 세트 그래프이다. 적절한 alpha 값은 두 그래프가 가장 가깝고 테스트 세트의 점수가 가장 높은 -1, 즉 10^-1 = 0.1이다.
최종적으로 alpha 값을 0.1로 해 모델을 훈련한다.
ridge = Ridge(alpha=0.1)
ridge.fit(train_scaled, train_target)
print(ridge.score(train_scaled, train_target))
# -> 0.9903815817570367
print(ridge.score(test_scaled, test_target))
# -> 0.9827976465386928
이 모델은 훈련 세트와 테스트 세트의 점수가 비슷하게 모두 높고, 과대적합과 과소적합도 일어나지 않았다.
라쏘 회귀
라쏘 모델도 릿지와 비슷하게 학습하면 된다. alpha 값을 조절해 최적의 규제 alpha 값을 찾는다.

import matplotlib.pyplot as plt
alpha_list = [0.001, 0.01, 0.1, 1, 10, 100]
train_score = []
test_score = []
for alpha in alpha_list:
#라쏘 모델을 만듭니다
lasso = Lasso(alpha=alpha, max_iter=10000)
#라쏘 모델을 훈련합니다.
lasso.fit(train_scaled, train_target)
#훈련 점수와 테스트 점수를 저장합니다.
train_score.append(lasso.score(train_scaled, train_target))
test_score.append(lasso.score(test_scaled, test_target))
plt.plot(np.log10(alpha_list), train_score)
plt.plot(np.log10(alpha_list), test_score)
plt.xlabel('alpha')
plt.ylabel('R^2')
plt.show()
라쏘 모델에서 최적의 alpha 값은 1, 즉 10^1 = 10이다.
이 값으로 다시 모델을 훈련한다.
from sklearn.linear_model import Lasso
lasso = Lasso(alpha==10)
lasso.fit(train_scaled, train_target)
print(lasso.score(train_scaled, train_target))
# -> 0.9908634969382497
print(lasso.score(test_scaled, test_target))
# -> 0.9836916306245592
릿지와 마찬가지로 라쏘 모델이 과대적합을 잘 억제하고 테스트 세트의 성능을 크게 높였다.
라쏘는 릿지와 달리 계수 값을 아예 0으로 만들 수 있다고 하였다.
print(np.sum(lasso.coef_ == 0))
# -> 40
55개의 특성을 모델에 주입하였지만 라쏘 모델이 사용한 특성은 15개밖에 되지 않는다. 이런 특징 때문에 라쏘 모델을 유용한 특성을 골라내는 용도로도 사용할 수 있다.
'2023-2 KHUDA > ML 기초세션' 카테고리의 다른 글
| [혼자 공부하는 머신러닝 + 딥러닝] Chapter 04-2 확률적 경사 하강법 (0) | 2023.08.15 |
|---|---|
| [혼자 공부하는 머신러닝 + 딥러닝] Chapter 04-1 로지스틱 회귀 (0) | 2023.08.15 |
| [혼자 공부하는 머신러닝 + 딥러닝] Chapter 03-2 선형회귀 (0) | 2023.08.08 |
| [혼자 공부하는 머신러닝 + 딥러닝] Chapter 03-1 k-최근접 이웃 회귀 (0) | 2023.08.08 |
| [혼자 공부하는 머신러닝 + 딥러닝] Chapter 02 데이터 다루기 (0) | 2023.08.08 |