8강 - 특성 공학과 규제 알아보기

2021. 6. 17. 21:59ICT 멘토링/혼자 공부하는 머신러닝+딥러닝

8강 - 특성 공학과 규제 알아보기

학습 로드맵

지난 시간에...

7강 복습

다중 회귀

multiple regression

multinomial regression

multinomial이 다항으로 해석되기도 하지만 의미는 다중 회귀임.

다중회귀

특성공학 - 새로운 특성 추가, 변경하는 것

 

판다스로 데이터 준비

import pandas as pd

df = pd.read_csv('https://bit.ly/perch_csv')
perch_full = df.to_numpy()

print(perch_full)
#//	[[8.4	2.11	1.41]
#	 [13.7	3.53	2.	]
#	 [15.	3.82	2.43]
#	 ...
#	 [43.5	12.6	8.14]
#	 [44.	12.49	7.6	]]

Pandas 핵심 구조 - 데이터프레임(DataFrame) : 여러 종류의 데이터 받을 수 있음 

                          엑셀 시트와 대응해 생각하면 쉬움

데이터 변환 과정

다항 특성 만들기

from sklearn.preprocessing import PolynomialFeatures

# degree=2
poly = PolynomialFeatures()
poly.fit([[2,3]])

# 1(bias), 2, 3, 2**2, 2*3, 3**2
print(poly.transform([[2, 3]]))
#//[[1. 2. 3. 4. 6. 9.]]

1 - 절편을 위한 특성

2, 3 - 그대로

4, 9 - 제곱

6 - 2*3

배열의 곱에서도 1을 고려

PolynomialFeatures - 변환기(Transformer)

   fit   transform

   실제로 뭔가를 학습하는 것은 아니고 조합을 파악하기만 함.

   개연성을 위해 fit method 사용

   fit_transform 제공. 하나로 fit, transform 두 과정 함.

LinearRegressor, KN- - 추정기(Estimator)

   fit -> predict -> score

 

LinearRegression

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()
# //['x0', 'x1', 'x2', 'x0^2', 'x0 x1',
	 'x0 x2', 'x1^2', 'x1 x2', 'x2^2']
test_poly = poly.transform(test_input)

절편 특성 빼기 위해서 include_bias=False로 함

배열의 크기 shape으로 확인 가능

get_feature_names()로 어떤 특성 있는지 확인 가능

PolynomialFeatures의 degree=2로 기본값을 가지므로 2차까지만 만들어짐. 

훈련세트에서의 변화는 테스트세트에서 그대로 사용하기 위해 테스트 세트를 위한 poly를 따로 만들지 않음.

 

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

훈련세트와 테스트세트 점수를 확인하니 과소적합 특성 사라짐.

9개의 특성으로 이전보다 특성 증가해서 그럼.

 

더 많은 특성 만들기

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.9999999999991097
print(lr.score(test_poly, test_target))
# //-144.40579242684848

차수가 5차로 55개의 특성을 가짐

훈련세트는 매우 높고 테스트 세트는 매우 안 좋음

하나도 못 맞춘 것이나 다름 없음

42개는 특성을 하나씩 맞추더라도 55개의 특성을 커버하지 못 해 모델의 정확도가 매우 낮아짐.

이런 극도의 과대적합한 모델도 규제를 둔다면 정확도가 높아질 수 있음.

정규화라는 표현으로 일반적으로 쓰이지만 이 책의 저자는 규제라는 표현을 사용하기로 함.

 

규제 - 가중치(기울기)를 작게 만드는 역할.

규제를 두는 것에는 Ridge, Lasso 2가지 방법이 존재함.

 

규제 전에 표준화

from sklearn.preprocessing import StandardScaler

ss = StandardScaler()
ss.fit(train_poly)

train_scaled = ss.transform(train_poly)
test_scaled = ss.transform(test_poly)

특성의 스케일이 비슷해져야지 각 기울기에게 주는 벌칙도 공평

스케일을 우선 맞춰야 함.

 

Z점수 - 표준점수

훈련 세트에 있는 통계값을 사용하는 것이므로 훈련 세트의 StandarScaler로 테스트 세트도 변환해줘야함

 

릿지 회귀(Ridge Regression)

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.9790693977615386

(가중치)^2 를 규제로 사용

->L2규제라고도 함.

선형회귀에 L2규제 적용시 릿지 회귀

 

Ridge 매개변수 alpha 존재

default alpha= 1

크게 하면 강도가 커지고 작게 하면 강도가 낮아짐.

 

알파값을 계속 바꿔가면서 정해줘야 함.

alpha - 하이퍼 파라미터

하이퍼 파라미터 탐색 과정 필요

 

가중치는 모델 클래스가 데이터로 학습하는 것이므로 모델 파라미터라고 함.

 

적절한 규제 강도 찾기

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

 

알파 리스트로 여러 개 만들어 for문에서 하나씩 훈련, 테스트 함

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.9827976465386922

이 모델에서는 알파값이 0.1 일 때가 최적 

 

 

라쏘 회귀(Lasso Regression)

|가중치| 를 벌칙으로 주기 때문에 L1규제를 적용한다고 함.

from sklearn.linear_model import Lasso

lasso = Lasso()
lasso.fit(train_scaled, train_target)

print(lasso.score(train_scaled, train_target))
# //0.98978989720896
print(lasso.score(test_scaled, test_target))
# //0.9800593698421883

 

릿지와 같이 알파 매개변수를 확인함.

데이터가 들쭉날쭉하지만 그래서 알파가 10일 때가 최적으로 보임.

 

일반적으로 L1규제보다 L2규제를 더 선호함.

규제가 효과적으로 잘 듦.

 

Lasso 특징은 가중치를 완전히 0으로 만들 수 있기 때문에 특성을 아예 사용하지 않을 수 있게 됨.

특성 * 가중치

 

어떤 특성을 사용하지 않는지 확인하기 위해서 lasso.coef_ == 0 인 것을 보면 됨.

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

print(np.sum(lasso.coef_ == 0))
# //40

55개 중 40개의 특성이 사용되지 않음.

15개만 Lasso에 대해서 사용.

 

 

참고자료

https://www.youtube.com/watch?v=PLECEclz0p4&list=PLVsNizTWUw7HpqmdphX9hgyWl15nobgQX&index=8