머신러닝

머신 러닝(with Google Colab) - 3일차(2)

aisw7984 2024. 10. 16. 15:20
반응형

3-2 특성 공학과 규제

이전까지는 단순히 길이와 무게로만 데이터를 판단했다. 그러나 현실에서는 다양한 특성들로 목표를 파악한다. 특성이 많아진다면 더 복잡한 모델을 설계할 수 있게 된다. 이때 기존특성을 가지고 새로운 특성을 만들어 내는 것을 특성공학이라고 한다.


특성공학에 들어가기 앞서 데이터를 준비해 보자 다양한 특성을 사용해야 하기 때문에 일일이 정보를 입력하는 것은 번거로운 작업이다. 따라서 Pandas를 통해 데이터를 불러와서 사용해 보자

Pandas의 데이터는 기본적으로 데이터프레임의 형태를 띠고 있는데 우리가 사용하는 Sklearn에 맞는 데이터 형태로 바꿔주기 위해서 Numpy의 형태로 바꿔줄 것이다.

import pandas as pd
df = pd.read_csv('https://bit.ly/perch_csv_data')
perch_full = df.to_numpy()

이제 나머지 정보들을 넣고 테스트, 훈련 세트로 나누어 주자

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)

 


사이킷런은 특성을 만들거나 전처리하기 위한 다양한 클래스를 제공하는데 이러한 클래스 들을 변환기라고 부른다. 변환기 클래스에는 모델 클래스에서 사용하는 fit(), score(), predict() 왕같이 제공하는 메서드처럼 공통적으로 fit()과 transfrom()을 제공한다.

우리가 사용할 변환기는  PolynomialFeatures 클래스이다. 이 클래스는 입력된 특성들을 제곱하고 서로 곱하고 절편을 추가하는 작업을 거쳐서 특성의 개수를 늘려준다. 

#변환기
from sklearn.preprocessing import PolynomialFeatures
poly = PolynomialFeatures(include_bias =False) 
train_poly = poly.fit_transform(train_input)
test_poly = poly.transform(test_input)
print(train_poly.shape)
=> (42, 9)

변환기에 input  데이터를 넣어주고 train_poly의 형태를 보면 특성이 9개로 늘어난 것을 확인할 수 있다.

앞서 규칙대로면 10개의 특성이 나와야 하지만. PolynomialFeatures()에 넣어준 include_bias =False는 절편의 유무를 결정하는 것으로 False를 했기 때문에 특성 1개가 제거된다.

이렇게 해주는 이유는 특성이 너무 많아지게 되면 과대 적합이 일어날 수 있기 때문이다.

get_feature_names_out() 메서드를 사용하면 어떤 형태의 특성이 생겼는지 확인할 수 있다.

poly.get_feature_names_out()
=> ['x0', 'x1', 'x2', 'x0^2', 'x0 x1', 'x0 x2', 'x1^2', 'x1 x2','x2^2']
 

이제 만들어진 데이터를 훈련시켜 확인해 보자

from sklearn.linear_model import LinearRegression
lr =LinearRegression()
lr.fit(train_poly, train_target)
print('훈련 정확도:',lr.score(train_poly, train_target))
print('테스트 정확도',lr.score(test_poly, test_target))
=>
훈련 정확도: 0.9903183436982125
테스트 정확도 0.9714559911594111

테스트 점수가 조금 낮긴 하지만 과소적합의 문제는 나타나지 않았다.

만약 특성이 더 늘어나면 어떻게 될까.  PolynomialFeatures클래스의 degree 매개변수를 사용하면 최대 차수를 정할 수 있다. degree를 5로 하고 결과를 확인해 보자

poly2 = PolynomialFeatures(include_bias=False, degree=5)
train_poly2 = poly2.fit_transform(train_input)
test_poly2 = poly2.transform(test_input)
print(train_poly2.shape)

from sklearn.linear_model import LinearRegression
lr = LinearRegression()
lr.fit(train_poly2, train_target)
print('훈련 정확도:',lr.score(train_poly2, train_target))   
=>
(42, 55)
훈련 정확도: 0.9999999999996433
테스트 정확도 -144.40579436844948

 

특성수가 55개까지 늘어난 것을 볼 수 있는데 훈련정확도는 1의 가까워졌지만 테스트 정확도가 매우 큰 음수값이 나오는 과대적합 문제가 크게 일어나는 것을 확인할 수 있다. 이때 필요한 것이 규제이다.


규제

규제는 머신러닝 모델이 훈련세트를 너무 과도하게 학습하지 못하도록 방해하는 것을 말한다.

선형 회귀 모델의 규제를 추가하는 모델을 릿지(ridge)와 라쏘(lass0)라고 부른다.

두 모델은 규제의 방식이 다르다. 일반적으로 릿지를 선호한다. 우선 객체를 초기화하고 각각을 알아보자

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))
print('테스트 정확도',ridge.score(test_scaled, test_target))

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

import matplotlib.pyplot as plt
#릿지 출력
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()

릿지 회귀는 사이킷런 linear_model 패키지 안에 Ridge 클래스를 사용하면 된다.

릿지와 라쏘는 alpha 값을 조절하여 정확도를 높일 수 있는데 alpha는 일일이 넣어가면서 최적의 값을 찾아야 한다. 이와 같이 사람이 직접 알려줘야 하는 파라미터를 하이퍼파라미터 라고 하고 이를 구하는 작업을 하이퍼파라미터 튜닝이라고 부른다. 결과를 확인해 보면 아래와 같다

훈련 정확도: 0.9857915060511934
테스트 정확도 0.9835057194929057

라쏘도 이와 같은 방식으로 할 수 있는데 Rige 자리에 Lasso를 넣어주면 된다.

반응형