1. 다중 회귀 multiple regression
여러 개의 특성을 사용한 선형 회귀
선형 회귀 모델이 학습하는 것
직선, 평면
직선
1개의 특성을 사용했을 때
평면
2개이 특성을 사용했을 때
특성이 3개일 경우는 상상할 수 없음.
특성이 많은 고차원에서
선형 회귀가 매우 복잡한 모델을 표현할 수 있음.
특성 공학 feature engineering
기존의 특성을 사용해 새로운 특성을 뽑아내는 작업
2. 데이터 준비
판다스 pandas
데이터 분석 라이브러리
데이터프레임 dataframe
판다스의 핵심 데이터 구조.
넘파이 배열로도 바꿀 수 있음.
데이터 다운로드
csv 파일
콤마로 나누어져 있는 텍스트 파일
import pandas as pd
df = pd.read_csv('https://bit.ly/perch_csv')
perch_full = df.to_numpy()
print(perch_full)

to_numpy()
데이터프레임을 넘파이 배열로 바꿔주는 메서드
타깃 데이터
import numpy as np
# http://bit.ly/perch_data
perch_length = np.array([8.4, 13.7, 15.0, 16.2, 17.4, 18.0, 18.7, 19.0, 19.6, 20.0, 21.0,
21.0, 21.0, 21.3, 22.0, 22.0, 22.0, 22.0, 22.0, 22.5, 22.5, 22.7,
23.0, 23.5, 24.0, 24.0, 24.6, 25.0, 25.6, 26.5, 27.3, 27.5, 27.5,
27.5, 28.0, 28.7, 30.0, 32.8, 34.5, 35.0, 36.5, 36.0, 37.0, 37.0,
39.0, 39.0, 39.0, 40.0, 40.0, 40.0, 40.0, 42.0, 43.0, 43.0, 43.5,
44.0])
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)
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)
3. 사이킷런의 변환기
변환기 transformer
특성을 만들거나 전처리하기 위한 사이킷런의 클래스
사이킷런의 변환기 클래스는
fit(), transform() 메서드를 제공
추정기 estimator
LinearRegression 같은 사이킷런의 모델 클래스
# 사용할 변환기 PolynomialFeatures 클래스
from sklearn.preprocessing import PolynomialFeatures
# 2개의 특성 2와 3으로 이루어진 샘플
poly = PolynomialFeatures()
poly.fit([[2, 3]])
print(poly.transform([[2, 3]]))
# 출력 결과 [[1. 2. 3. 4. 6. 9.]]
PolynomialFeatures 클래스
각 특성을 제곱한 항을 추가하고
특성끼리 서로 곱한 항을 추가함.
1은 왜 추가되었나?
선형 방정식의 절편을 항상 값이 1인 특성과 곱해지는 계수

사이킷런의 선형 모델은 자동으로 절편을 추가함.
include_bias=False 설정해서 추가하지 않을 수 있음.
# 절편을 포함하지 않는 경우
poly = PolynomialFeatures(include_bias=False)
poly.fit([[2, 3]])
print(poly.transform([[2, 3]]))
# 출력 결과 [[2. 3. 4. 6. 9.]]
train_input에 적용
poly = PolynomialFeatures(include_bias=False)
poly.fit(train_input)
train_poly=poly.transform(train_input)
print(train_poly.shape)
# 출력 결과 (42, 9)
poly.get_feature_names_out()
# 출력 결과 ['x0', 'x1', 'x2', 'x0^2', 'x0 x1', 'x0 x2', 'x1^2', 'x1 x2', 'x2^2']
test_poly = poly.transform(test_input)
get_feature_names() → get_feature_names_out()
9개의 특성이 어떻게 만들어졌는지 확인하는 메서드
* 이슈사항: 메서드명 변경됨.
4. 다중 회귀 모델 훈련하기
from sklearn.linear_model import LinearRegression
lr = LinearRegression()
lr.fit(train_poly, train_target)
print(lr.score(train_poly, train_target))
# 출력 결과 0.9903183436982124
print(lr.score(test_poly, test_target))
# 출력 결과 0.9714559911594134
농어 길이만 사용했을 때의 과소적합 문제 해결!
특성을 더 많이 추가해보자.
5제곱까지 특성을 만들어보자.
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.9999999999991098
print(lr.score(test_poly, test_target))
# 출력 결과 -144.40579242684848
훈련 세트에 과대적합됨.
특성을 줄여아함.
5. 규제
규제 regularization
머신러닝 모델이 훈련 세트를 과도하게 학습하지 못하도록 훼방하는 것.
특성의 스케일
특성의 스케일이 정규화되지 않으면
여기에 곱해지는 계수 값도 차이 나게 됨.
일반적으로 선형 회귀 모델에 규제를 적용할 때 계수 값의 크기가 서로 많이 다르면 공정하게 제어되지 않음.
from sklearn.preprocessing import StandardScaler
ss = StandardScaler()
ss.fit(train_poly)
train_scaled = ss.transform(train_poly)
test_scaled = ss.transform(test_poly)
train_scaled, test_scaled에
표준점수로 반환한 값이 담겨있음.
StandardScaler 클래스 객체의
mean_ 학습한 평균 저장됨
scale_ 학습한 표준편차 저장됨
선현 회귀 모델에 규제를 추가한 모델
릿지 ridge, 라쏘 lasso
릿지 ridge
계수를 제곱한 값을 기준으로 규제를 적용
일반적으로 더 선호함.
라쏘 lasso
계수의 절대값을 기준으로 규제를 적용
릿지와 라쏘 모두 계수의 크기를 줄이지만,
라쏘는 아예 0으로 만들 수도 있음.
6. 릿지 회귀
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.9790693977615398
많은 특성을 사용했음에도 불구하고
훈련 세트에 과대적합되지 않음.
테스트 세트에서도 좋은 성능을 내고 있음.
alpha 매개변수로 규제의 강도 조절 가능.
값이 크면 규제 강도가 세지므로
계수 값을 줄이고 과소적합되도록 유도.
값이 작으면 계수를 줄이는 역할이 줄어들고
선형 회귀 모델과 유사해짐.
과대적합 주의!
하이퍼파라미터 hyperparameter
사람이 직접 지정해야하는 매개변수.
릿지 모델에서 alpha 값은 모델이 학습하는 값이 아니라 사전에 사람이 지정하는 값.
적절한 alpha 값 찾는 방법
alpha 값에 대한 R² 값의 그래프를 그려보기.
import matplotlib.pyplot as plt
train_score = []
test_score = []
alpha_list = [0.001, 0.01, 0.1, 1, 10, 100]
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, label='train')
plt.plot(np.log10(alpha_list), test_score, label='test')
plt.legend()
plt.show()

그래프의 왼쪽은 훈련 세트와 테스트 세트의 점수 차가 큼. 과대적합의 모습. |
그래프의 오른쪽은 훈련 세트와 테스트 세트의 점수가 모두 낮아짐. 과소적합. |
ridge = Ridge(alpha = 0.1)
ridge.fit(train_scaled, train_target)
print(ridge.score(train_scaled, train_target))
# 출력 결과 0.9903815817570366
print(ridge.score(test_scaled, test_target))
# 출력 결과 0.9827976465386926
7. 라쏘 회귀
from sklearn.linear_model import Lasso
lasso = Lasso()
lasso.fit(train_scaled, train_target)
print(lasso.score(train_scaled, train_target))
# 출력 결과 0.9897898972080961
print(lasso.score(test_scaled, test_target))
# 출력 결과 0.9800593698421883
train_score = []
test_score = []
alpha_list = [0.001, 0.01, 0.1, 1, 10, 100]
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, label='train')
plt.plot(np.log10(alpha_list), test_score, label='test')
plt.legend()
plt.show()

lasso = Lasso(alpha = 10)
lasso.fit(train_scaled, train_target)
print(lasso.score(train_scaled, train_target))
# 출력 결과 0.9888067471131867
print(lasso.score(test_scaled, test_target))
# 출력 결과 0.9824470598706695
과대적합을 억제하고
테스트 세트의 성능을 높임.
계수값이 0인 것 헤아려 보기
print(np.sum(lasso.coef_ == 0))
# 출력 결과 40
np.sum()
배열을 모두 더한 값을 반환
'머신러닝 > 혼공머신' 카테고리의 다른 글
혼공머신 | Chap 04-1. 로지스틱 회귀 (0) | 2022.09.01 |
---|---|
혼공머신 | Chap 03-2. 선형 회귀 (0) | 2022.08.23 |
혼공머신 | Chap 03-1. k-최근접 이웃 회귀 (0) | 2022.08.22 |
혼공머신 | Chap 02-2. 데이터 전처리 (0) | 2022.08.17 |
혼공머신 | Chap 02-1. 훈련 세트와 테스트 세트 (0) | 2022.08.11 |