[혼공머신] 회귀 알고리즘과 모델 규제

Jinyeong Choi·2024년 8월 5일
0

ML

목록 보기
3/6

k-최근접 이웃 회귀

지도 학습 알고리즘은 크게 분류회귀로 나뉜다.

회귀는 클래스 중 하나로 분류하는 것이 아니라 임의의 어떤 숫자를 예측하는 문제
두 변수 사이의 상관관계를 분석하는 방법

k-최근접 이웃 회귀

분류와 같이 예측하려는 샘플에 가장 가까운 샘플 k개를 선택.
회귀이기 때문에 이웃한 샘플의 타깃은 어떤 클래스가 아니라 임의의 수치임에 주의.
이웃 샘플의 수치들의 평균을 구하여 새로운 심플의 타깃을 예측.

특성 1개만 사용하기 때문에 수동으로 2차원 배열을 만들어야 한다.
reshape() 메서드를 이용.

  • reshape() 메서드는 크기가 바뀐 새로운 배열을 반환할 때 지정한 크기가 원본 배열에 있는 원소의 개수와 다르면 에러가 발생.
  • reshape(-1, 1)과 같이 사용하면 배열의 전체 원소 개수를 외우지 않아도 됨

결정계수(R^2)

사이킷런에서 k-최근접 이웃 회귀 알고리즘을 구현한 클래스는 KNeighborsRegressor

from sklearn.neighbors import KNeighborsRegressor

knr = KNeighborRegressor()

# k-최근접 이웃 회귀 모델을 훈련
knr.fit(train_input, train_target)

# 결정계수
print(knr.score(test_input, test_target))
# 0.9928094061010639

분류의 경우 테스트 세트에 있는 샘플을 정확하게 분류한 개수의 비율(즉, 정확도)을 알아볼 때 사용한 score() 메서드는 회귀의 경우 결정계수를 알아낼 때 사용한다. 사이킷런의 score() 메서드가 출력하는 값(정확도나 결정계수)은 높을수록 좋은 것이다.

  • 회귀에서는 예측하는 값이나 타깃 모두 임의의 수치이기 때문에 정확한 숫자를 맞힌다는 것은 거의 불가능하다.

coefficient of determination
R^2 = 1- (target - prediction)^2 / (target - average)^2

타깃의 평균 정도를 예측하는 수준이라면 (분자와 분모가 비슷해져) 결정계수는 0에 가까워지고, 타깃이 예측에 아주 가까워지면 (분모가 0에 가까워지기 때문에) 1에 가까운 값이 된다.

과대적합 vs 과소적합

모델을 훈련 세트에 훈련하면, 훈련 세트에 잘 맞는 모델이 만들어진다. 훈련세트와 테스트 세트에서 평가하면 두 값 중 보통 훈련 세트의 점수가 조금 더 높게 나오게 된다. 훈련 세트에서 모델을 훈련했기 때문이다.

  • 훈련 세트테스트 세트의 점수를 비교했을 때, 훈련세트가 너무 높으면 overfitting, 그 반대이거나 두 점수가 모두 낮으면 underfitting!

과대적합 overfitting

만약 훈련 세트에서 점수가 굉장히 좋았는데 테스트 세트에서는 점수가 굉장이 나쁘다면 모델이 훈련 세트에 과대적합 되었다고 말한다.
즉, 훈련 세트에만 잘 맞는 모델이라 테스트 세트와 나중에 실전에 투입하여 새로운 샘플에 대한 예측을 만들 때 잘 동작하지 않을 것.

과소적합 underfitting

훈련 세트보다 테스트 세트의 점수가 높거나 두 점수가 모두 너무 낮은 경우 모델이 훈련 세트에 과소적합 되었다고 말한다.
즉, 모델이 너무 단순하여 훈련 세트에 적절히 훈련되지 않은 경우.

  • 과소적합이 일어나는 이유:
    훈련 세트와 테스트 세트의 크기가 매우 작을 때에도 과소적합 발생 가능
  • 과소적합을 해결하는 방법:
    모델을 조금 더 복잡하게 만들자!

훈련 세트가 전체 데이터를 대표한다고 가정하기 때문에 훈련 세트를 잘 학습하는 것이 중요!!!

선형 회귀

k-최근접 이웃의 한계

새로운 샘플이 훈련 세트의 범위를 벗어나면 엉뚱한 값을 예측할 수 있다.
k-최근접 이웃을 사용해 이 문제를 해결하려면 범위를 조정하여 훈련 세트를 다시 만들어야 한다.

주기적으로 훈련되어야 하는 머신러닝 모델!
시간과 환경이 변화하면서 데이터도 바뀌기 때문에 주기적으로 새로운 훈련 데이터로 모델을 훈련해야 한다.

선형 회귀 Linear Regression

사이킷런은 sklearn.linear_model 패키지 아래에 LinearRegression 클래스로 선형 회귀 알고리즘을 구현해 두었다. 클래스의 객체를 만들어 훈련하기!

from sklearn.linear_model import LinearRegression
lr = LinearRegression()

# 선형 회귀 모델을 훈련
lr.fit(train_input, train_target)

# 50cm 농어에 대해 예측
print(lr.predict([[50]])

y = ax + b (a는 기울기, b는 y절편)
LinearRegression 클래스가 데이터에 가장 잘 맞는 a와 b를 찾는 것.
a는 lr 객체의 coef_ 속성에
b는 lr 객체의 intercept_ 속성에 저장
되어 있다.

Model Parameter
모델 파라미터는 머신러닝 알고리즘이 찾은 값이라는 의미이며, 머신러닝 알고리즘의 훈련 과정은 최적의 모델 파라미터를 찾는 것과 같다. 이를 모델 기반 학습이라고 부른다.
k-최근접 이웃의 경우 훈련세트를 저장하는 것이 훈련의 전부였기 때문에 모델 파라미터가 없다. 이를 사례 기반 학습이라고 부른다.

다항 회귀 Polynomial Regression

2차 방정식의 그래프를 1차 방정식 그래프 대신에 그리게 되면 어떨까?
2차 방정식 그래프를 회귀 곡선으로서 그리려면 길이를 제곱한 항이 훈련 세트에 추가되어야 한다.
numpy를 이용하여 간단하게!

# 제곱한 항 만들기
train_poly = np.column_stack((train_input ** 2, train_input))
test_poly = np.column_stack((test_input ** 2, test_input))

# 선형 회귀 모델을 다시 훈련
lr = LinearRegression()
lr.fit(train_poly, train_target)

print(lr.predict([[50**2, 50]])

print(lr.coef_, lr.intercept_)
# [1.0433211 -21.55792498] 116.0502107827827

2차 방정식도 선형 회귀인 이유
길이를 제곱한 항을 1차인 다른 변수로 치환하게 되면 일차식이 되는 것처럼 선형 관계로 표현할 수 있다.

다항 회귀

다항식을 사용한 선형 회귀.
다항 회귀 알고리즘을 통해 2차 방정식의 계수와 절편 a, b, c를 알게 됨.

선형 회귀로 훈련 세트 범위 밖의 샘플 예측

k-최근접 이웃 회귀의 한계(아무리 멀리 떨어져 있더라도 무조건 가장 가까운 샘플의 타깃을 평균하여 예측)를 해결하기 위해 선형 회귀를 사용. 선형 회귀는 k-최근접 이웃 회귀와 다르게 훈련 세트를 벗어난 범위의 데이터도 예측 성공.
선형 회귀의 한계? 모델이 단순하여 데이터의 범위를 벗어나는 경우 발생(데이터가 무조건 양수여야하는데, 음수인 데이터를 말하는 경우)
선형 회귀의 한계를 해결하기 위해 다항 회귀 사용.

과소적합된 경향을 해결하는 방법과 과대적합된 모델을 반대로 억제하는 방법

특성 공학과 규제

다중 회귀 multiple regression

여러 개의 특성을 사용하는 회귀 모델.
특성이 많으면 선형 모델은 강력한 성능을 발휘.
multiple regression
특성이 2개면 타깃값과 함께 3차원 공간을 형성하고 선형 회귀 방정식은 평면이 된다.
3차원 공간 이상을 그리거나 상상할 수는 없지만, 분명한 것은 선형 회귀를 단순한 직선이나 평며느올 생각하여 성능이 무조건 낮다고 오해하면 안된다. 특성이 많은 고차원에서는 선형 회귀가 매우 복잡한 모델을 표현할 수 있다.

특성 공학 feature engineering

주어진 특성을 조합하여 새로운 특성을 만드는 일련의 작업 과정.
직접 특성을 제곱하고 특성끼리 곱해서 새로운 특성을 추가할 수도 있지만 보통 사이킷런에서 제공하는 도구를 사용

판다스 pandas

유명한 데이터 분석 라이브러리

데이터프레임 dataframe

판다스의 핵심 데이터 구조이며, 넘파이 배열과 비슷하게 다차원 배열을 다룰 수도 있지만 훨씬 더 많은 기능을 제공한다.

import pandas as pd

# 판다스가 파일을 읽는 방법
# 판다스 데이터 프레임 설정 
df = pd.read_csv('https://bit.ly/perch_csv')

# 넘파이 배열로 전환
perch_full = df.to_numpy()
print(perch_full)

사이킷런의 변환기

변환기 transformer

사이킷런에서는 특성을 만들거나 전처리하는 클래스를 변환기라고 부름.
사이킷런의 모델 클래스에 일관된 fit(), score(), predict() 메서드가 있는 것처럼, 변환기 클래스는 모두 fit(), transform() 메서드를 제공.

# 사용할 변환기 PolynomialFeatures 클래스 불러오기
from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures()

# 훈련
poly.fit([[2,3]])

# 변환
print(poly.transform([[2,3]])

fit() : 새롭게 만들 특성 조합 탐색
transform() : 실제 데이터로 변환

  • 변환기는 입력 데이터를 변환하는 데 타깃 데이터가 필요하지 않는다.
    모델 클래스와는 다르게 fit()에 입력 데이터만 전달함.

transform 전에 꼭 fit을 사용해야하는가?
훈련을 해야 변환이 가능하다. 사이킷런의 일관된 api 때문에 두 단계로 나뉘어져 있다. 두 메서드를 하나로 붙인 fit_transform 메서드도 있다.

poly = PolynomialFeatures(include_bias=False)
poly.fit([[2,3]])
print(poly.transform([[2,3]]))

PolynomialFeatures 클래스는 기본적으로 각 특성을 제곱한 항을 추가하고 특성끼리 서로 곱한 항을 추가한다.
무게 = a 길이 + b 높이 + c 두께 + d 1
선형 방정식의 절편을 항상 값이 1인 특성과 곱해지는 계수. 특성 = (길이, 높이, 두께, 1)
사이킷런의 선형 모델은 자동으로 절편을 추가하므로 굳이 이렇게 특성을 만들 필요가 없음.

  • include_bias=False
    사이킷런 모델은 자동으로 특성에 추가된 절편 항을 무시하는 역할
    굳이 지정해주지 않아도 역할 수행

다중 회귀 모델 훈련하기

다중 회귀 모델을 훈련하는 것은 선형 회귀 모델을 훈련하는 것과 같다.
다만 여러 개의 특성을 사용하여 선형 회귀를 수행하는 것.

특성을 더 많이 추가? 3제곱, 4제곱 항을 추가? PolynomialFeatures 클래스의 degree 매개변수를 사용하여 필요한 고차항의 최대 차수를 지정할 수 있음

# 5제곱까지 특성을 만들기
poly = PolynomialFeautres(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)
lr.fit(train_poly, train_target)
print(lr.score(train_poly, train_target))
# 0.99999999999

결정계수가 음수인 경우

print(lr.score(test_poly, test_target))
# -144.40579242684848

특성의 개수를 크게 늘리면 선형 모델은 훈련 세트에 대해 거의 완벽하게 학습할 수 있다. 하지만 이런 모델의 경우, 훈련 세트에 너무 과대적합되므로 테스트 세트에서는 형편없는 점수를 만든다.
문제 해결 방법? 특성 줄이기 (과대적합 줄이는 방법 중 하나)

규제 Regularization

과대적합을 줄이는 방법
규제는 머신러닝 모델이 훈련 세트를 너무 과도하게 학습하지 못하도록 훼방하는 것.
즉, 모델이 훈련 세트에 과대적합되지 않도록 만드는 것. 선형 회귀 모델의 경우 특성에 곱해지는 계수(또는 기울기)의 크기를 작게 만드는 일.

from sklearn.preprocessing import StandardScaler

# StandardScaler 클래스의 객체를 생성 및 초기화
ss = StandardScaler()

# PolynomialFeatures 클래스로 만든 train_poly를 이용하여 객체를 훈련
ss.fit(train_poly)

# 훈련 세트로 학습한 변환기를 사용해 테스트 세트까지 변환
train_scaled = ss.transform(train_poly)
test_scaled = ss.transform(test_poly)

반드시 훈련 세트로 학습한 변환기를 사용하여 테스트 세트까지 변환해야 한다!!!!!

선형 회귀 모델에 규제를 추가한 모델을 릿지 ridge와 라쏘 lasso라고 부른다.
릿지와 라쏘 모두 sklearn.linear_model 패키지 안에 있다.
릿지: 계수를 제곱한 값을 기준으로 규제를 적용
라쏘: 계수의 절댓값을 기준으로 규제를 적용

릿지 회귀

규제가 있는 선형 회귀 모델 중 하나이며 선형 모델의 계수를 작게 만들어 과대적합을 완화시킴.
비교적 효과가 좋아 널리 사용하는 규제 방법.

from sklearn.linear_model import Ridge
ridge = Ridge()
ridge.fit(train_scaled, train_target)
print(ridge.score(train_scaled, train_target))

많은 특성을 사용했음에도 불구하고 훈련 세트에 너무 과대적합되지 않아 테스트 세트에서도 좋은 성을 냄.

라쏘

또 다른 규제가 있는 선형 회귀 모델.
릿지와 달리 계수 값을 아예 0으로 만들 수도 있음.

from sklearn.linear_model import Lasso
lasso = Lasso()
lasso.fit(train_scaled, train_target)
print(lasso.score(train_sclaed, train_target))

하이퍼파라미터 hyperparameter

머신러닝 알고리즘이 학습하지 않는 파라미터.
하이퍼파라미터의 경우 사람이 사전에 지정해야 함.
대표적으로 릿지와 라쏘의 규제 강도 alpha 파라미터이다.

alpha로 규제의 강도를 조절
alpha 값이 크면 규제 강도가 세지므로 계수 값을 더 줄이고 조금 더 과소적합되도록 유도.
alpha 값이 작으면 계수를 줄이는 역할이 줄어들고 선형 회귀 모델과 유사해지므로 과대적합될 가능성 증가.

적절한 alpha 값을 찾는 방법
alpha 값에 대한 R^2(결정계수) 값의 그래프를 그려보는 것!
훈련 세트와 테스트 세트의 점수가 가장 가까운 지점이 최적의 alpha 값이 된다.

profile
Hang in there

0개의 댓글

관련 채용 정보