본문 바로가기
머신러닝/혼공머신

[혼공머신] chapter 3. 회귀 - k최근접, 릿지/라쏘

by 다이노소어 2022. 12. 1.
혼자 공부하는 머신러닝 + 딥러닝의 Chapter 3을 공부하면서 정리한 내용을 기반으로 작성하였다.

 

 

03-1. k-최근접 이웃 회귀

- 회귀문제 다루는 법을 맛보는 장이다.


분류와 회귀

머신러닝 알고리즘은 지도학습 알고리즘과 비지도학습 알고리즘으로 나뉜다고 Chapter 02에서 배웠다. 여기서 지도 학습 알고리즘은 크게 분류와 회귀(regression)로 나뉜다. 분류는 샘플을 클래스 중 하나로 분류하는 것이고, 회귀는 분류하는 것이 아니라 임의의 숫자를 예측하는 것이다. 회귀는 정해진 클래스가 없고 임의의 수치를 출력한다.

분류 - 샘플을 클래스 중 하나로 분류하는 것
회귀 - 분류하는 것이 아니라 임의의 숫자를 예측하는 것
- 회귀는 정해진 클래스가 없고 임의의 수치를 출력한다.

cf ) 회귀 알고리즘의 시작 및 어원

: 과거 한 학자가 키 큰 사람의 자녀가 부모보다 크지 않다는 것을 보고 '평균으로 회귀한다'고 표현.

  이후, 두 변수 사이의 상관관계를 분석하는 방법을 회귀라 부름

 

 

k-최근접 이웃 회귀

k-최근접 이웃 분류 알고리즘은 가장 가까운 샘플 k를 선택해서 그 샘플들의 클래스를 기반으로 새로운 샘플의 클래스를 예측한다. 이 때, 새로운 샘플의 클래스는 다수 클래스를 기준으로 예측된다.

k-최근접 이웃 회귀 알고리즘은 가장 가까운 샘플 k를 선택해서 그 샘플들의 타깃들을 평균내어 새로운 샘플의 타깃값을 예측한다.

 

k-최근접 이웃 회귀 알고리즘을 구현한 클래스는 KNeighborsRegressor이다.

from sklearn.neighbors import KNeighborsRegressor

knr = KNeighborsRegressor()

 

 

1. 데이터 준비

     → 농어의 길이를 가지고 무게를 예측한다고 가정

  • 농어의 길이를 특성으로 하고, 농어의 무게를 타깃으로 해서 넘파이 배열을 만든다 : 넘파이의 array()
  • 훈련 세트와 테스트 세트로 나눈다 : train_test_split() 
  • 사이킷런에 사용할 훈련 세트는 2차원 배열이어야 한다. : {적용할 arry}.reshape(-1, 1)
    • 나머지 원소 개수로 다 채우려면, 크기에 -1을 지정하면 된다

 

 

2. 결정계수 (R^2)

knr.score(test_input, test_target)을 하면,

  •  분류의 경우,  테스트 세트의 샘플을 정확하게 분류한 개수의 비율 즉, 정확도를 알려준다.
  •  회귀의 경우, 결정계수(coefficient of determination ; R^2)을 알려준다.
결정계수  → 0 이라면, 타깃의 평균 정도를 예측하고 있다는 의미
결정계수  → 1 이라면, 타깃에 아주 가깝게 예측하고 있다는 의미 

 

3. 평균 절댓값 오차

sklearn.metrics 패키지에는 여러 측정 도구를 제공한다. 그 중 mean_absolute_error()은  타깃과 예측의 절댓값 오차를 평균해서 반환한다

from sklearn.metrics import mean_absolute_error

test_prediction = knr.predict(test_input) #예측 : 앞서 지정한 범위 test_input에 대한 예측
mae = mean_absolute_error(test_target, test_predicttion)

 

4. 과대적합 vs 과소적합

과대적합 (overfitting)
(1) 훈련 세트 점수는 좋지만, 테스트 세트 점수가 나쁠 때

→ 특히, 그 차이가 심할 때 모델이 훈련세트에 과대적합된 것이다. 즉, 훈련 세트에만 잘 맞는 모델인 것이다.

과소적합 (underfitting)
(1) 훈련 세트보다 테스트 세트 점수가 높을 때
(2) 훈련 세트와 테스트 세트 모두 점수가 낮을 때

→ 모델이 너무 단순하여 훈련 세트에 적절히 훈련되지 않을 때,
    작은 데이터를 사용했을 때, 과소적합이 일어난다.

* 과소적합을 해결하기 위해서는 모델을 복잡하게 만들면된다. 

k-최근접 이웃 알고리즘에서는 이웃의 개수(k)를 줄여서 모델을 복잡하게 만들 수 있다. k가 줄어들면 훈련 세트의 국지적인 패턴에 민감하고, k가 늘어나면 훈련 세트 데이터 전반의 일반적인 패턴을 따른다. (k default value = 5)

 

 

 

5.  k-최근접 이웃의 한계

  • 새로운 샘플이 훈련 세트의 범위를 벗어나면 엉뚱한 값을 예측할 수 있다.
    • 예를 들어, 농어 50cm의 무게를 예측한다고 할 때, 농어 50cm와 가장 가까운 샘플들의 무게를 평균한다.
    • 샘플 중 농어 50cm와 가장 가까운 길이가 45cm라면, 농어 45cm 샘플들의 무게를 평균한 값으로 예측한다.
    • 0~45cm 농어의 무게 샘플을 있을 때, 100cm 농어의 무게를 예측하라고 하면 엉뚱한 값을 예측하는 것이다.
  • k-최근접 이웃을 사용해 이 문제를 해결하려면 훈련세트를 다시 만들어야 한다. 그러지 말고, 선형회귀로 해결해보자!

 


[ 참고 ]
머신러닝 모델은 주기적으로 훈련해야 한다. 데이터는 계속 바뀌기 때문에, 새로운 데이터를 사용해 훈련을 반복해야 한다.

 

 

 

 

 

03-2. 선형 회귀

- 데이터 범위 밖에서도 예측할 수 있도록!


선형회귀

- 최적의 직선 찾기

- linear regression

- 훈련 세트 범위 벗어난 샘플 예측을 할 수 있다.

- 널리 사용되는 대표적인 회귀 알고리즘

 

선형 회귀 알고리즘을 구현한 클래스는 sklearn.linear_model 패키지 아래의 LinearRegression 클래스이다.

from sklearn.linear_model import LinearRegression

lr = LinearRegression()
  •  LinearRegression와 같은 모델 클래스는 추정기(estimator)라고도 부른다.
  •  LinearRegression 클래스에도 fit(), score(), predict() 메서드가 있다.
  • 선형회귀의 객체의 coef_에는 기울기가, intercept_속성에는 절편이 저장되어 있다. (ex) lr.coef_ , lr.intercept_
    • 머신러닝에서 기울기를 종종 coefficient(계수) 또는 weight(가중치)라고 부른다.
    • coef_와 intercept_를 모델 파라미터라고 부른다.
    • fit_intercept 매개변수를 False로 지정하면 절편을 학습하지 않는다 (기본값 : True)
[참고] 모델 파라미터 : model parameter (머신러닝 알고리즘이 찾은 값을 의미)
모델 기반 학습 - 최적의 모델 파라미터를 찾는 머신러닝 알고리즘 훈련 과정
사례 기반 학습 - 훈련 세트를 저장하는 것이 전부인 머신러닝 알고리즘 훈련 과정 (ex. k-최근접 이웃)

 

다항회귀

- 최적의 곡선 찾기

- polynomial regression (다항식(polynomial)을 사용한 선형회귀) : 선형회귀에 포함됨

- 2차 방정식 그래프를 그리려면 특성 테이터를 제곱한 항이 훈련세트와 테스트세트에 추가되어야 한다.

   → [ex] np.column_stack((array **2, array))

 

 

 

 


03-3. 특성 공학과 규제

- 과소적합 문제를 해결하기 위해 제곱보다 더 고차항을 넣어야 한다!


다중회귀

- multiple regression

- 여러 개의 특성을 사용한 선형회귀

 

 

특성 공학 (feature engineering)

 : 기존의 특성을 사용해 새로운 특성을 뽑아내는 작업이다.

예시로 이해해보자. 이전 예시는 농어의 길이를 특성으로 두었다면, 농어의 길이, 높이, 두께를 사용한다. 이 특성들을 각각 제곱하거나 서로 곱해서 새로운 특성으로 추가한다. 사이킷런 변환기를 이용하자

 

▷ 사이킷런 변환기(transformer) - PolynomialFeatures

from sklearn.preprocessing import PolynomialFeatures

poly = PolynomialFeatures()
#poly = PolynomialFeatures(degree=5, include_bias=False)
#degree : 최대차수 지정, include_bias=False : 특성에 추가된 절편한 무시(default : False)
poly.fit(train_input)
train_poly = poly.transform(train_input)
test_poly = poly.transform(test_input)
  • 특성 만들거나 전처리하기 위한 클래스
  • 변환기 클래스에는 fit(), transform() 메소드가 내장되어 있다.
  • fit_transform() : 훈련(fit)을 해야 변환(transform)이 가능하다 (fit + transfrom = fit_transform() )
  • get_feature_names_out() : 최종 만들어진 특성이 어떤 조합으로 만들어졌는지 알려준다.

※ 특성의 개수가 늘어나면 선형모델은 강력해지지만 훈련 세트에 너무 과대적합된다. 즉, 테스트 세트의 점수가 극명하게 낮아진다.

 

 

규제(regularization)

- 과대적합되지 않도록 한다

- 선형 회귀 모델의 특성에 곱해지는 계수 또는 기울기 크기를 작게 만든다.

 

 사이킷런 변환기(transformer) - StandardScaler

from sklearn.preprocessing import StandardScaler

ss= StandardScaler()

#PolynomialFeatures클래스로 만든 train_poly와 test_poly를 사용
ss.fit(train_poly) #[1] 훈련세트로 학습
train_scaled = ss.transfrom(train_poly) #[2] 훈련세트 표준점수로 변환
test_scaled = ss.transfrom(test_poly) #[2] 테스트세트 표준점수로 변환
  1. PolynomialFeatures 클래스로 만든 transfrom 과정을 마친 훈련세트로 ss 객체를 학습시킨다. 이 때, 반드시 훈련세트로 학습시켜야 한다.
  2. 이후, 학습한 변환기를 사용해 훈련세트와 테스트 세트를 표준점수로 변환한다

 

 

릿지 회귀와 라쏘 회귀

  • 선형 회귀모델에 규제를 추가한 모델
  • 릿지와 라쏘는 sklearn.linear_model 패키지 안에 있다.
from sklearn.linear_model import Ridge
from sklearn.linear_model import Lasso
  • 릿지와 라쏘 또한 마찬가지로 fit()로 훈련하고 score()로 평가한다.
  • 알파(alpha) : 릿지와 라쏘 모델의 객체를 만들 때, 알파를 매개변수로 하여 규제의 강도를 조절할 수 있다.
    • alpha 값이 클수록 : 규제강도 세져 계수 값 줄어듦 -> 과소적합 유도
    • alpha 값이 작을수록 : 계수 줄이는 규제 약해짐 -> 선형 회귀 모델(규제없음)과 유사해짐 -> 과대적합 가능성이
    • ※ 적절한 alpha 값을 찾는 방법
      - 'alpha - R^2(score) 그래프'를 그려 보는 것입니다.
      - 테스트 점수가 최대면서도, 훈련세트와테스트 세트 점수의 차이가 최소일 때 적절한 alpha를 가진다. 즉, 훈련세트와 테스트 세트의 점수가 비슷하게 높아야 한다.

 

 

릿지 회귀 ridge

  • 계수를 제곱한 값을 기준으로 규제를 적용한다.
ridge = Ridge(alpha = 10) #모델 객체 생성, alpha 값을 임의로 10으로 둠
ridge.fit(train_scaled, train_target)
train_score = ridge.score(train_scaled, train_target)
test_score = ridge.score(test_scaled, test_target)

 

 

라쏘 회귀 lasso

  • 계수의 절댓값을 기준으로 규제를 적용한다.
  • 매개변수 : alpha, max_iter (최대 반복횟수)
  • 계수값을 0으로 만들 수 있다.
    • 계수가 0이라는 것은 모델이 해당 특성을 쓰지 않았다는 의미
    • 계수가 0인 것을 제외해 유용한 특성을 골라내는 용도로 라쏘 모델을 사용할 수 있다.
lasso = Lasso(alpha = 10) #모델 객체 생성, alpha 값을 임의로 10으로 둠
lasso.fit(train_scaled, train_target)
train_score = lasso.score(train_scaled, train_target)
test_score = lasso.score(test_scaled, test_target)

import numpy as np
unused_property = np.sum(lasso.coef_ == 0) #모델이 쓰지 않는 특성들 개수

 

 

 

 

 

 

 

 

 


**참고

plt.plot([15, 50], [15*lr.coef+lr.intercept_, 50*lr.coef_ + lr.intercept_])
#x 범위 : 15 ~ 50
#y 값 : ax+b(a : lr.coef_, b : lr.intercept_)
# scatter() 점찍기, plot() 그래프그리기, xlabel 혹은 ylabel 각 축의 라벨 붙이기
 pandas datafram

- 데이터프레임은 판다스(데이터 분석 라이브러리)의 핵심 데이터 구조이다.

csv 파일                      datagram           →           numpy array
                  read_csv()                        to_numpy()
하이퍼파라미터(hyperparameter)

- 머신러닝 모델이 학습할 수 없고 사람이 알려줘야 한는 파라미터
- 머신러닝 라이브러리(ex.사이킷런)에서 하이퍼파라미터는 매개변수로 표현된다.