본문 바로가기
혼공학습단 머신러닝+딥러닝

[혼공머신] 2주차 - 회귀 모델과 규제

by 알래스카코코넛 2024. 1. 12.
반응형

Ch.3 회귀 알고리즘과 모델 규제 

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

 지도학습은 크게 분류와 회귀 2가지로 나뉩니다. 1주차에서 했던 분류와, 이번 주차에 볼 '예측'에 해당되는 분류가 있습니다. 간단하죠? 그런데 머신러닝 입문 단계에서는 프로젝트를 할 때, 내 프로젝트가 분류인지 예측인지 어려운 경우도 종종 있어서 프로젝트의 목적을 분명히 해야 합니다. 예를 들어, '연봉으로 2억원을 받는 야구선수는 어떤 포지션일 확률이 높을까?' 같은 경우에는 분류일까요, 회귀(예측)일까요? 약간 헷갈리시나요? 언듯 보면 포지션을 예측하는거 아닌가요? 라고 할 수도 있습니다. 이번 단원에서는 회귀(예측)과 분류 알고리즘의 차이를 명확히 보고, 분류 알고리즘의 예시와 더 나아가서 규제까지 정리해보겠습니다.

 

 회귀 알고리즘이란, 두 변수 사이의 상관관계를 분석하는 방법으로 예측과 동치라고 생각하셔도 큰 문제는 없습니다. 다만 영어로 Regression을 사용하기 때문에 이를 그대로 번역하는 과정에서 조금 더 직관적인 회귀라는 단어가 되었습니다. 이번에는 농어의 길이, 높이, 두께 데이터를 통해서 무게를 예측하는 문제를 해결하며 회귀 알고리즘을 배워보겠습니다.

 

 2장에서 제가 제일 많이 사용한 단어는 아마 k-최근접 이웃입니다. 이번에도 k-최근접 이웃 알고리즘을 사용하는데, 대신 회귀 모델로 적용시켜보겠습니다. 근데 어떻게요?

 

 k-최근접 알고리즘의 최대 장점은 간단함입니다. 이 방법을 살려, k-최근접 이웃 알고리즘이 회귀(예측)을 수행하는 방법은 가장 가까운 k개의 샘플의 값의 평균값이 알고자 하는 값이라고 결론내는 것입니다. 오류가 많지 않냐고요? 확실히 예측치가 정확하지는 않습니다. 그런데 장점은 뭐다? 이 문단 첫 줄에 있죠. 간단합니다. 그래서 정밀한 예측이 아닐 때 빠르게 사용하기 좋습니다. 그림으로 나타내면 이렇습니다.

 

 위 그림과 같이, 주황색 세모의 값을 알아내기 위해 k=4인 k-최근접 이웃 알고리즘을 통한 회귀를 수행하면 빨간색 동그라미의 값이 40, 25, 30, 20이므로 이들의 평균인 28.75가 주황색 세모의 값입니다. 쉽죠?

 

 그럼 다시 풀고자 하는 문제로 돌아와서, 농어의 길이를 통해 무게를 예측해보겠습니다. 다른 높이, 두께 데이터는 사용 안하냐고요? 우선 이번 알고리즘은 길이만 이용해서 예측해보고, 이후에 더 복잡한 알고리즘을 배우면 두개 이상의 데이터로 하나의 값을 예측해보겠습니다. 우선 데이터를 준비합시다. 

 

농어 데이터를 가지러 가니 먼저 데이터를 가져간 사람들의 발자국이 많이 보이네요. 저도 이 책 1회독 할 때 한 마디 남기고 갔었습니다. 안농, 농어야! 

import numpy as np

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]
     )

 

이 데이터만 봐서는 샘플의 분포가 어떻게 되어있는지 잘 모르겠습니다. ch.1에서 했듯이 산점도를 찍어봅시다. 

import matplotlib.pyplot as plt

plt.scatter(perch_length, perch_weight)
plt.xlabel('length')   #주어진 특성을 x값으로
plt.ylabel('weight')   #알고자 하는 값을 y값으로 
plt.show()

상당히 길이와 무게의 비례관계가 잘 보인다.

 

산점도를 찍으니 무게와 길이가 관계가 있다는 점이 잘 보입니다. 만약 비례관계가 잘 안보이면 어떻게 하냐고요? 가능하면 다른 특성을 이용하는 편을 추천드립니다. 이번 특성은 관계가 아주 잘 보이니, 그대로 머신러닝을 진행하면 될 것 같습니다. 

 

 머신러닝을 시킬 때 해야하는 기본적인 스텝이 있습니다 머신러닝이 복잡해보이지만, 사실 본질은 저 4단계가 다입니다. 

1. 데이터 살펴보기

2. 데이터를 (테스트 세트와 훈련 세트로)나누기

3. 머신러닝 시키기

4. 예측(혹은 분류) 실행하기

 

1번 데이터 살펴보기는 산점도로 이미 완료했네요! 그럼 이번에는 데이터를 테스트 세트와 훈련 세트로 나눌 차례입니다. 그런데 왜 '테스트 세트와 훈련 세트로' 부분에 괄호가 있냐고요? 이후 챕터에서 배우지만, 다른 세트 하나가 더 등장하기 때문입니다. 이제 2번 데이터를 나누면 되는데, 우리는 이미 Ch.1에서 sklearn의전지전능함을 이용해서 충분히 데이터를 섞고, 나누어주는 함수를 알고 있습니다. train_test_split()함수를 이용하면, 일일이 노가다나 긴 코드를 작성하지 않아도 1줄 만에 적절한 훈련 세트와 테스트 세트를 얻을 수 있습니다. 

from sklearn.model_selection import train_test_split

train_input, test_input, train_target, test_target = train_test_split(
    perch_length, perch_weight, random_state=42)  
#random_state는 다른 숫자를 넣어도 무방합니다. 단, 교재와 숫자를 통일하기 위해 42로 설정하였습니다. 
    
print(train_input.shape, test_input.shape)

(42,) (14,)

 

그런데 이전 k-최근접 이웃 분류 모델을 사용하였을 때, 데이터 결과가

[[25.4, 242.0], [26.3, 290.0], [26.5, 340.0], [29.0, 363.0], [29.0, 430.0], [29.7, 450.0], [29.7, 500.0], [30.0, 390.0], [30.0, 450.0], [30.7, 500.0], [31.0, 475.0], [31.0, 500.0], [31.5, 500.0], [32.0, 340.0], [32.0, 600.0], [32.0, 600.0], [33.0, 700.0], [33.0, 700.0], [33.5, 610.0], [33.5, 650.0], [34.0, 575.0], [34.0, 685.0], [34.5, 620.0], [35.0, 680.0], [35.0, 700.0], [35.0, 725.0], [35.0, 720.0], [36.0, 714.0], [36.0, 850.0], [37.0, 1000.0], [38.5, 920.0], [38.5, 955.0], [39.5, 925.0], [41.0, 975.0], [41.0, 950.0], [9.8, 6.7], [10.5, 7.5], [10.6, 7.0], [11.0, 9.7], [11.2, 9.8], [11.3, 8.7], [11.8, 10.0], [11.8, 9.9], [12.0, 9.8], [12.2, 12.2], [12.4, 13.4], [13.0, 12.2], [14.3, 19.7], [15.0, 19.9]]

 

이렇게 출력되었던 부분이 기억나시나요? 안 나면 다시 보고 옵시다. 

https://alasco-footprint.tistory.com/15

 

[혼공머신] 1주차 -1 오프닝과 k-최근접 이웃 알고리즘

0. 혼공학습단 머신러닝+딥러닝 시작 오프닝 멘트 여름방학 때 혼공C로 참여하고 반 년이 흘러 혼공머신으로 돌아왔습니다. 머신러닝은 파이썬을 쓰니까 두 주제가 연관이 없을 것 같은데 왜 머

alasco-footprint.tistory.com

 사이킷런에서 사용할 훈련 세트는 위 결과처럼 2차원 배열이여야 합니다. 그런데 (42,) (14,)는 1차원 배열이네요. 이 점은 reshape()를 이용해서 쉽게 바꿀 수 있습니다. 

train_input = train_input.reshape(-1, 1)   #첫 번째 값은 알아서 하고, 2번째 값은 1로 해서 2차원 배열을 만들어라
test_input = test_input.reshape(-1, 1)   #너도 2차원 배열로 바뀌어라 

print(train_input.shape, test_input.shape)  #배열 형태 확인

 (42,1) (14,1)

아주 간단하게 바뀌었습니다. 이제 데이터도 잘 나누었으니, 3번 머신러닝 시키기로 넘어가겠습니다. 

 

from sklearn.neighbors import KNeighborsRegressor

knr = KNeighborsRegressor()  #공장 생성 
knr.fit(train_input, train_target)  #공장 가동

knr.score(test_input, test_target)  #공장 성능 확인
# 0.992809406101064

 

성능이 0.99... 아주 좋은 숫자가 나왔습니다. 이전에 언급했듯이, 1.0이면 완벽히 분류(혹은 예측), 0.5면 반만 성공, 0이면 싹 다 틀렸다는 의미입니다. 회귀에서는 저 값을 결정계수(coefficient of determination), 쉽게 R² 이라고도 합니다. 계산 방법은 '1-(타깃-예측) ²의 합/(타깃-평균) ²의 합'으로 아주 간단해서 교수님들의 단골 단답형 시험문제니 시험 기간이시라면 슬쩍 외워두시는 편을 추천합니다. 

 

과대적합(overfitting)과 과소적합(underfitting)

여기는 정말 중요한 부분이라 따로 정리해서 링크를 올려두었습니다.

https://alasco-footprint.tistory.com/18

 

[1.5주차] 과대적합과 과소적합

과대적합(overfitting)과 과소적합(underfitting)에 대해서는 따로 챕터를 빼서 알아보겠습니다. 내용이 많지는 않은데, 상당히 중요한 내용이라 별도로 분리했습니다. 사실 정의 자체는 각각 1줄이면

alasco-footprint.tistory.com

머신러닝의 성능을 신뢰할 수 있냐 없냐를 결정짓는 요소가 과대적합/과소적합이 일어났는가? 이고, 아무리 뛰어난 코드로 머신러닝을 실행시켰어도 과대적합이나 과소적합이 일어났으면 해당 모델은 사용하기 어렵습니다. 따라서 이 링크를 통해서 과대적합과 과소적합을 꼭 알아두고 가시길 추천드립니다. 

 

그럼 과대적합/과소적합이 일어났는지 확인해봅시다. 테스트 세트 점수는 알고 있으니, 훈련 세트 점수를 확인해서 비교하면 되겠죠?

print(knr.score(train_input, train_target))
#0.9698823289099254

 

 0.969로 약간 낮긴 한데, 사실 기계학습에서 이 정도 낮은건 낮은 축에도 못 끼기 때문에 적합하게 훈련되었다고 할 수 있습니다. 그런데 만약 값이 마음에 들지 않으면 어떻게 하면 될까요?

 보통 모델이 너무 복잡하면 과대적합, 너무 단순하면 과소적합이 일어납니다. 그러면 반대로, 과대적합이 발생하였을 때는 단순하게 만들기를 유도하고, 과소적합이 발생했다면 복잡하게 되도록 유도하면 되겠네요! 따라서 해결 방법은 k-최근접 이웃 알고리즘에서는 k 값이 작아질수록 국지적인 패턴에 민감해지므로 과소적합을 해결할 수 있고, k값이 크면 과대적합을 해결할 수 있습니다. 헷갈린다면 쉽게 외워버리는 것도 하나의 방법입니다.

 

k값 작다 ->다 -> 과적합 방지

k값 크다 -> 다 -> 과적합 방지 

 

3-2 선형 회귀(Linear Regression)

k-최근접 이웃 회귀는 주변 데이터의 평균을 특성값으로 예측하기 때문에, 어느 정도 범위를 벗어난 예측을 하기 어렵습니다. 즉, 예측의 범위에 한계가 존재합니다. 이러한 단점을 극복하고자, 드디어 그 유명한 선형회귀(Linear Regression)가 등장합니다. 선형회귀의 특징은 특성의 분포를 바탕으로 직선을 학습하는 것입니다. 직관적으로 이해가 어려우면, 중학교 시절에 배운 간단한 수학을 하나 가져오겠습니다. 

 

사분면 위에 (3,6), (4,8), (2,4), (2.5,5)라는 점들이 찍혀있다고 가정합시다. 이들을 모두 이으면 y = 2x 방정식이 등장하죠. 이제 이 방정식을 따르는 (50,t)라는 점이 등장할 때, t의 값을 예측할 수 있을까요? 당연히 100이겠죠. 이처럼 선형회귀는 

 

  1. 주어진 데이터로 방정식을 알아낸다.
  2. 알고자 하는 값을 해당 방정식에 대입한다

이 절차로 값을 예측하는 회귀 알고리즘입니다. 쉽죠? 참고로 저 방정식을 알아내는 건 우리의 친구 sklearn이 데이터와 명령어(코드)를 입력하기만 하면 알아서 계산해줍니다. 오늘도 sklearn에게 한번 더 감사를 하고 넘어갑시다.

 

그러면 이론은 어느 정도 알았으니, 직접 코드를 살펴보겠습니다.

from sklearn.linear_model import LinearRegression

lr = LinearRegression()  #선형 회귀 모델 선언 (=공장 만들기)

lr.fit(train_input, train_target) #공장 가동
print(lr.predict([[50]]))  #50cm짜리 농어 무게 예측
#[1241.83860323]

 

1241.8386g이라네요. 꽤 신뢰할 만한 결과가 도출되었습니다. 그리고 선형 방정식의 기울기와 y절편이 궁금하다면 이 또한 코드를 통해서 알아낼 수 있습니다.

print(lr.coef_, lr.intercept_)
#[39.01714496] -709.0186449535477

 

coef_는 계수(coefficient)를 의미하고, intercept_는 절편을 의미합니다. 즉, y = ax+b에서 a가 coef, b가 intercept입니다. 이제 진짜로 sklearn이 믿을 만한 방정식을 그린거 맞아? 내가 안 본다고 거짓말 한거 아냐? 라고 의문을 품는 여러분을 위해 실제 방정식의 생김새도 코드를 통해 알아봅시다.

 

plt.scatter(train_input, train_target) # 산점도 그리기

#방정식 그리기 
plt.plot([15, 50], [15*lr.coef_+lr.intercept_, 50*lr.coef_+lr.intercept_])

plt.scatter(50, 1241.8, marker='^') # 50cm 농어 데이터 예측

plt.xlabel('length')
plt.ylabel('weight')
plt.show()

 

예쁘게 방정식을 잘 그렸네요. 마지막으로 공장의 성능을 평가해보겠습니다.

 

print(lr.score(train_input, train_target))
print(lr.score(test_input, test_target))

#0.939846333997604
#0.8247503123313558

 

테스트 세트의 점수가 0.82라 약간 안 좋네요. 특히 왼쪽 아래 꼬리 부분이 방정식이랑 좀 많이 다릅니다. 그러면 방정식을 직선이 아닌, 곡선으로 찾으면 성능을 더 향상시킬 수 있을 것 같습니다. 방정식을 y = ax² + bx + c 형태로 두고 a, b, c를 찾아보겠습니다. 이렇게 곡선, 즉 여러 항을 이용한 회귀 알고리즘을 다항회귀라고 합니다. 그런데 이차방정식은 이전에 없던 ax²항이 추가되었으니, x² 데이터도 추가로 입력해줘야 합니다. 일일이 노가다 뛰긴 우리의 시간과 손가락은 소중하니, 코드 2줄로 제곱데이터를 만들어줍시다.

 

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]]))  #예측 실행
#[1573.98423528]

 

이번에는 50cm의 무게를 1573.984로 예측했습니다. 이번에도 파이썬 녀석의 농땡이가 의심되니, a, b, c의 엄밀한 값과 방정식의 생김새를 내놓으라고 요구해봅시다.

print(lr.coef_, lr.intercept_)

#차례로 a,       b,          c의 값 
[  1.01433211 -21.55792498] 116.0502107827827

#그래프의 x축 구간을 15~50 으로 설정
point = np.arange(15, 50)

#산점도 그리기 
plt.scatter(train_input, train_target)

# 방정식 그래프 표시- 1.01은 lr.coef_의 첫 번째 값(a), 21.6은 lr.coef_의 2번째 값(b)
# 116.05는 lr.intercept_ (c)
plt.plot(point, 1.01*point**2 - 21.6*point + 116.05)

# 50cm 농어 삼각형으로 표시 
plt.scatter([50], [1574], marker='^')
plt.xlabel('length')
plt.ylabel('weight')
plt.show()

 

 

일차방정식보다 그래프가 예쁘네요. 정말정말 마지막으로 공장의 성능을 측정합시다. 성능 측정은 뭐다? lr.score()

 

print(lr.score(train_poly, train_target))
print(lr.score(test_poly, test_target))

#0.9706807451768623
#0.9775935108325122

 

이전보다 확실히 성능이 향상되었고, 과대적합/과소적합이 모두 일어나지 않았습니다. 아주 좋네요!

3-3. 다중회귀와 특성 공학과 규제

 사실 무언가를 예측한다면, 한 가지 요소로 예측하는 것보다는 두 가지 이상의 요소로 예측하는 편이 더 좋겠죠. 예를 들어, 어느 후보의 득표율을 예측할 때 현재 지지율 외에도 이전 득표율, 후보자의 경력 기간, 연령별 선호도 등 여러가지 요인을 포함하는 편이 더 좋습니다. 이처럼 여러 개의 특성을 이용하여 선형회귀를 실시하는 방법을 다중회귀(multiple regression)이라고 합니다. 이전에 배운 다항회귀와는 이름이 비슷하니 헷갈리지 않도록 주의합시다. 

 

 추가로, 원래 데이터에서 특성의 개수가 적어도 더 늘릴 수 있는 방법이 있습니다. 몸무게와 키를 통해서 (몸무게)/(키)²인 BMI를 특성으로 사용할 수도 있고, 몸무게x키를 새로운 요소로도 사용할 수 있습니다. 이처럼 기존의 특성을 이용해서 새로운 특성을 뽑아내는 작업을 특성공학(feature engineering)이라고 합니다. 

 

 다중회귀와 특성공학의 정의를 알았으니 이번에도 코드로 실습하면서 알아봅시다.

import pandas as pd

df = pd.read_csv('https://bit.ly/perch_csv_data')
perch_full = df.to_numpy()
#print(perch_full)

 

데이터의 용량이 커서 직접 코드에 명시하기 어렵다면 pandas의 read_csv()함수를 이용해서 쉽게 csv 파일을 들고올 수 있습니다. 

 

import numpy as np

 #타깃 데이터는 그냥 코드에서 언급하겠습니다. 
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)

 

 데이터를 모두 들고와서 테스트 세트와 훈련 세트로 나누었습니다. 이제 특성 공학을 이용하겠습니다. 어떻게 할 거냐고요? 머신러닝에서 어떻게 할지 모르겠으면 뭐다? sklearn에게 물어본다. 역시 우리의 구세주 sklearn은 특성 공학을 적용하는 방법도 알고 있습니다. 특성 공학을 적용하는 클래스를 변환기(transformer) 이라고 하며, 모델명.fit(), 모델명.transform()을 사용합니다. 

from sklearn.preprocessing import PolynomialFeatures  #변환기 임포트 

poly = PolynomialFeatures(include_bias=False)  #절편항 무시 - 굳이 필요 없기 때문
#사실 include_bias 없이도 자동으로 절편항을 무시하긴 합니다. 

poly.fit(train_input) 
train_poly = poly.transform(train_input)
test_poly = poly.transform(test_input)

 

이제 진짜 진짜 데이터가 준비되었으니, 공장을 가동시켜 봅시다!

 

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

 

 변환기를 통해서 특성 공학을 거친 데이터를 이용한 선형회귀는 점수가 아주아주 높네요. 굿입니당

 

 이번에는 5제곱 항까지 특성을 늘려서 다중회귀를 시켜보겠습니다. 특성을 1가지만 사용했을 때 이차항으로 만드니 점수가 더 좋아졌으니, 이번에도 점수가 더 높아지지 않을까요?

 

poly = PolynomialFeatures(degree=5, include_bias=False)

poly.fit(train_input)
train_poly = poly.transform(train_input)
test_poly = poly.transform(test_input)

lr.fit(train_poly, train_target)
print(lr.score(train_poly, train_target))
#0.9999999999996433

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

 

 와! 테스트 세트의 점수가 -144가 나왔습니다. 무슨 뜻일까요? 망했다는 의미죠.

 

 충격적인 숫자를 뒤로 하고, 일단 무슨 문제가 발생했는지 봅시다. 훈련 세트의 점수 >>>> 테스트 세트의 점수네요. 이 경우에는 과대적합이 일어났습니다. 과대적합이 일어난 경우, 모델을 단순하게 하면 해결된다고 언급한 적이 있습니다. 기억 안나면 반성하세요. 따라서 모델을 단순하게 하는 방법인 규제를 알아봅시다.

 

 규제

규제(regularization)은 이처럼 모델이 훈련 세트를 과도하게 학습하지 못하도록 의도적으로 방해하는 것을 의미합니다. 선형 회귀에는 릿지(Ridge)와 라쏘(Lasso) 회귀가 대표적인 규제입니다. 길게 언급할 내용은 아니니, 짧고 간단히 정리하겠습니다.

  릿지 회귀 라쏘 회귀
규제 방법 계수를 제곱한 값을 기준으로 규제 적용 계수의 절댓값을 기준으로 규제 적용
특징 계수가 0이 되지 않음 계수가 0이 될 수 있음 
공통점 계수의 크기를 줄여준다(=모델을 단순하게 만든다)

 

특징을 알았으니 코드로 규제를 적용해봅시다.

#공통적으로 데이터 전처리 실행
from sklearn.preprocessing import StandardScaler

ss = StandardScaler()
ss.fit(train_poly)

train_scaled = ss.transform(train_poly)
test_scaled = ss.transform(test_poly)
#릿지 회귀 실시 
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값을 지정해서, 계수의 크기를 변경할 수 있습니다. 이처럼 프로그래머가 직접 설정하는 매개변수를 하이퍼파라미터라고 하고, 이와는 달리 모델과 관련된 파라미터는 모델 파라미터라고 합니다. 

 

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)  
plt.plot(np.log10(alpha_list), test_score)

plt.xlabel('alpha')
plt.ylabel('R^2')
plt.show()

alpha = -1일때 최적의 성능이 나타나는 것 같습니다. 라쏘 회귀도 마찬가지로 적용할 수 있는데, 이 부분은 릿지와 코드가 거의 비슷하므로 코드를 작성하지는 않겠습니다. 정 알고 싶으시면 댓글이나 ChatGPT에게.... 

 

이제 지이인짜 마지막 미션 하고 정리 끝! 

기본미션: Ch.03(03-1) 2번 문제 출력 그래프 인증하기

 

선택 미션: 모델 파라미터에 대해 설명하기. 참고로 하이퍼파라미터의 정의와 종류도 아주 중요하므로 헷갈리지 말라고 같이 적어뒀슴당.

  모델 파라미터 참고) 하이퍼 파라미터
정의 머신러닝 모델이 학습하여 얻은 파라미터. 임의로 조작할 수 없다. 사전에 사람(프로그래머)가 지정해줘야 하는 파라미터
예시 선형회귀의 가중치, 절편 등  규제의 alpha값, 이후에 나올 learning rate (=lr), k-최근접 이웃 알고리즘에서 k의 값 등)

 

반응형