머신러닝

[ML]11. 모델 정규화

CodeJaram 2023. 8. 31. 11:16

머신러닝_11_모델 정규화

 

  1. 특성곱
  • 선형회귀모델은 특성의 수가 적으면 모델이 단순해져 성능이 저하됨
  • 선형회귀모델은 하이퍼 파라미터 조절을 할 수 없음

→각 특성의 데이터를 곱해서 특징의 수를 늘려서 모델의 성능 개선

  • 1차 함수 그래프(직선)를 2차 함수 그래프(곡선)그래프로 변환



2. 선형회귀모델 정규화: 선형회귀모델에서 과대적합을 제어하기 위해 w값의 비중 낮춤

  • 선형회귀모델이 지나치게 최적화되면 모형계수의 크기도 지나치게 증가함(과적합)
  • 선형회귀계수(w) 값에 제약을 주어 모델이 과도하게 최적화되는 현상 방지

 

1)Lasso(L1 정규화): 가중치의 절대값의 합을 최소화하는 제약조건

  • w의 모든 원소에 똑같은 힘으로 규제를 적용하는 방법
  • 불필요한 특성 계수들은 0이 됨(불필요한 특성 삭제)
  • 특성 선택이 자동으로 이루어짐
  • 특정 특성들의 연관성이 강할 때 사용,  연관성 없는 특성 삭제

 

2)Ridge(L2 정규화): 가중치의 제곱합을 최소화하는 제약 조건

  • w의 모든 원소의 골고루 규제를 적용하여 0에 가깝게 만듦
  • 모든 특성들이 연관성이 어느 정도 있을 때 사용, 모든 특성을 골고루 규제

 

3)엘라스틱넷: L1+L2

  • 하이퍼파라미터(강도(alpha), L1, L2 선택하는 비율) 

 

→Ridge는 모든 특성을 규제하지만, Lasso는 연관성 높은 특성만 남겨서 규제함

 

4)매개변수: alpha(규제의 강도)



[보스턴 주택 가격 예측 실습]

7. 특성곱

  • 원본 데이터 가져와서 복사하기

#원본데이터 가져와서 복사하기

#->pandas.DataFrame.copy()

#코드 실행 중 데이터 프레임의 상태 복사하는 기능

 

boston_copy=boston.copy()

 

  • 컬럼 상관관계 확인하기

#상관계수 확인

boston_copy.corr()

 

#히트맵으로 상관관계 확인하기

 

plt.figure(figsize=(15,15))

sns.heatmap(data=boston_copy.corr(),

            annot=True, #상관계수 히트맵에 표시

            annot_kws={'size' :12}, #상관계수 글자 크기

            fmt='.2f', #소수점 제한

            cmap='Greens'

            )

 

#MEDV와 상관관계 높은 컬럼->RM(주택의 방 개수), LSTAT(인구 중 하위 계층의 비율)

#특성곱

#1. MEDV와 상관관계 높은 컬럼을 제곱

#2. MEDV와 상관관계 있는 전체 컬럼 제곱

 

1)LSTAT 컬럼 특성곱 적용

 

  • LSTAT 컬럼만 학습하고 예측한 뒤 시각화하기

#특성곱 확장 전 LSTAT 특성만 가지고 학습하고 예측

 

#모델링

lr_model=LinearRegression()

 

#모델 학습

lr_model.fit(X_train[['LSTAT']], y_train)

 

#모델 예측

pre=lr_model.predict(X_train[['LSTAT']])

 

#산점도 그래프 그리기

#.scatter(문제 데이터, 답지 데이터)

plt.scatter(X_train[['LSTAT']], y_train) #실제 답

plt.scatter(X_train[['LSTAT']], pre, color='red') # 예측한 답

 

plt.xlabel('LSTAT')

plt.ylabel('MEDV')

plt.show()

 

  • train 데이터 LSTAT 컬럼에 특성곱 적용 후 학습하고 예측한 뒤 시각화하기

#특성곱 확장 후 LSTAT와 LSTAT 특성을 제곱 후 학습하고 예측

 

#특성곱 적용한 새로운 컬럼 생성하기

# X_train['LSTAT x LSTAT'] = X_train['LSTAT'] **2

X_train['LSTAT_square'] = X_train['LSTAT'] * X_train['LSTAT']

 

#모델링

lr_model2 = LinearRegression()

lr_model2.fit(X_train[['LSTAT', 'LSTAT_square']], y_train)

#모델 학습

pre2 = lr_model2.predict(X_train[['LSTAT', 'LSTAT_square']])

 

#산점도 그래프 그리기

#.scatter(문제 데이터, 답지 데이터)

plt.scatter(X_train[['LSTAT']], y_train) # scatter 산점도 그려주는 함수, 실제 답

plt.scatter(X_train[['LSTAT']], pre2, color='red') # scatter 산점도 그려주는 함수, 예측 답

 

plt.xlabel('LSTAT_square')

plt.ylabel('MEDV')

plt.show()

 

 

  • test 데이터에 LSTAT 특성 곱 적용하고 학습/평가하기

#테스트 데이터 중 LSTAT 특성만 제곱하여 특성제곱 전후 비교

X_test['LSTAT_square']=X_test['LSTAT'] * X_test['LSTAT']

 

#모델링

lr_model3=LinearRegression()

 

#모델 학습

lr_model3.fit(X_train, y_train)

lr_model3.score(X_test, y_test)

 

#일반모델 0.7085045269202357



2)RM 컬럼 특성곱 적용하기

  • train 데이터 RM 컬럼 특성곱 적용하고 학습/예측하기

#특성곱 확장

#RM와 RM특성을 제곱 후 학습하고 예측

#새로운 컬럼

# X_train['LSTAT x LSTAT'] = X_train['LSTAT'] **2

X_train['RM_square'] = X_train['RM'] * X_train['RM']

 

#모델링

lr_model11 = LinearRegression()

 

#모델 학습

 

lr_model11.fit(X_train[['RM', 'RM_square']], y_train)

 

#모델 예측

pre11 = lr_model11.predict(X_train[['RM', 'RM_square']])

 

 

#산점도 그래프 그리기

#.scatter(문제 데이터, 답지 데이터)

plt.scatter(X_train[['RM']], y_train) # scatter 산점도 그려주는 함수, 실제 답

plt.scatter(X_train[['RM']], pre11, color='red') # scatter 산점도 그려주는 함수, 예측 답

plt.show()

 

  • test 데이터 RM 컬럼 특성곱 적용하고 학습/평가하기

#테스트 데이터 중 RM 특성만 제곱하여 특성제곱 전후 비교

X_test['RM_square']=X_test['RM'] * X_test['RM']

 

#모델링

lr_model3=LinearRegression()

 

#모델 학습

lr_model3.fit(X_train, y_train)

lr_model3.score(X_test, y_test)

 

 

#일반모델 0.7085045269202357

#LSTAT 제곱: 0.7752718351923247



3)모든 컬럼에 특성곱 적용하기

  • 원본데이터 복제

#데이터 복제

 

extend_X_train=X_train.copy()

extend_X_test=X_test.copy()

 

  • 경고창 무시하기

#경고창 무시하기

 

import warnings

warnings.filterwarnings('ignore')

 

  • train 데이터 모든 컬럼 특성곱 적용하기

#반복문을 이용하여 train 데이터 모든 컬럼 특성곱 적용하기

 

for col1 in X_train.columns: #13번 반복

  for col2 in X_train.columns:

    #특성곱 컬럼 추가

    extend_X_train[col1+ 'x'+col2]=X_train[col1]* X_train[col2]

 

  • text 데이터 모든 컬럼 특성곱 적용하기

#반복문을 이용하여 test 데이터 모든 컬럼 특성곱 적용하기

 

for col1 in X_test.columns: #13번 반복

  for col2 in X_test.columns:

    #특성곱 컬럼 추가

    extend_X_test[col1+ 'x'+col2]=X_test[col1]* X_test[col2]

 

  • 모델 학습/평가

#모델 생성

lr_model22=LinearRegression()

 

#모델 학습

lr_model22.fit(extend_X_train, y_train)

lr_model22.score(extend_X_test, y_test)

 

#train 데이터 score 출력

lr_model22.score(extend_X_train, y_train)

#test 데이터 score출력

lr_model22.score(extend_X_test, y_test)

 

-test 데이터보다 train 데이터의 score가 더 높음=>과적합 발생

-원인: 특성곱으로 특성이 너무 많아짐

-해결방법: 모델의 정규화



8. 모델 정규화

#규제 모델 import

 

from sklearn.linear_model import Lasso # L1

from sklearn.linear_model import Ridge # L2

from sklearn.linear_model import ElasticNet # ElasticNet

 

1)L1(Lasso) 모델

#L1 모델 생성

#alpha값으로 규제 강도 설정

#alpha 값이 높아지면 규제 강도가 커지고 과대적합 위험성 감소, 오차 증가

 

lasso_model=Lasso(alpha=10)

 

#L1 모델 학습

lasso_model.fit(extend_X_train, y_train)

#가중치->.coef_

print('가중치: ', lasso_model.coef_) #가중치(w)

 

#Lasso는 필요없는 특성의 가중치(w) 값을 0으로 바꾸기 때문에

0이 아닌 가중치(w) 값의 개수를 구하면 학습에 사용된 특성의 개수를 알 수 있음

 

#점수: np.sum(lasso_model.coef_!=0)

print(f'사용되는 특성의 개수: {np.sum(lasso_model.coef_!=0)}')

전체 182개 컬럼 중 연관성이 높은 48개 컬럼만 사용

 

#L1 모델 예측

 

#과대적합 제어정도를 확인하기 위해 train, test데이터 각각 예측

pre_lasso_train= lasso_model.predict(extend_X_train)

pre_lasso_test= lasso_model.predict(extend_X_test)

 

#회귀 평가지표(MSE, RMSE)

#평가지표가 0에 가까울수록 좋은 모델

 

#MSE: mean_squared_error(예측답지, 실제 답지)

#잔차: train MSE에서 test의 MSE를 뺀 값

train_mes_lasso=mean_squared_error(pre_lasso_train, y_train)

test_mes_lasso=mean_squared_error(pre_lasso_test, y_test)

 

#MSE 값 확인

print(f'train 데이터 MSE 값: {train_mes_lasso}')

print(f'test 데이터 MSE 값: {test_mes_lasso}')

print(f'MES 잔차: {train_mes_lasso-test_mes_lasso}')

 

#RMSE 값 확인: np.sqrt(MSE)

print(f'train 데이터 RMSE 값: {np.sqrt(train_mes_lasso)}')

print(f'test 데이터 RMSE 값: {np.sqrt(test_mes_lasso)}')

print(f'RMSE 잔차: {np.sqrt(train_mes_lasso)-np.sqrt(test_mes_lasso)}')

 

#lasso model train score

np.round(lasso_model.score(extend_X_train, y_train),2)

 

#lasso model test score

np.round(lasso_model.score(extend_X_test, y_test),2)

#일반모델 성능 점수

-lr 모델 extend X_train의 score: 0.93

-lr 모델 extend X_test의 score: 0.87

->잔차: 6

 

#lasso 모델 성능점수

-lasso model train score: 0.86

-lasso model test score 0.82

->잔차 4

 

#규제모델 사용 후 과적합 감소(잔차 6→4), 예측률은 감소(0.87→0.82)

 

2)L2(Ridge) 모델 

#Ridge 모델 생성

ridge_model=Ridge(alpha=10)

 

#학습

ridge_model.fit(extend_X_train, y_train)

 

#가중치->.coef_

print('가중치: ', ridge_model.coef_)

 

#점수: np.sum(ridge_model.coef_!=0)

print(f'사용되는 특성의 개수: {np.sum(ridge_model.coef_!=0)}')

#L2모델은 모든 특성을 골고루 규제하므로 모든 특성을 사용함

 

#ridge 모델 예측

#과대적합 제어 정도를 확인하기 위해 train, test데이터 각각 예측

pre_ridge_train= ridge_model.predict(extend_X_train)

pre_ridge_test= ridge_model.predict(extend_X_test)

 

#회귀 평가지표(MSE, RMSE)

#평가지표가 0에 가까울수록 좋은 모델

 

#MSE: mean_squared_error(예측답지, 실제 답지)

#잔차: train MSE에서 test의 MSE를 뺀 값

train_mes_ridge=mean_squared_error(pre_lasso_train, y_train)

test_mes_ridge=mean_squared_error(pre_lasso_test, y_test)

 

#MSE 값 확인

print(f'train 데이터 MSE 값: {train_mes_ridge}')

print(f'test 데이터 MSE 값: {test_mes_ridge}')

print(f'MES 잔차: {train_mes_ridge-test_mes_ridge}')

 

#RMSE 값 확인: np.sqrt(MSE)

print(f'train 데이터 RMSE 값: {np.sqrt(train_mes_ridge)}')

print(f'test 데이터 RMSE 값: {np.sqrt(test_mes_ridge)}')

print(f'RMSE 잔차: {np.sqrt(train_mes_ridge)-np.sqrt(test_mes_ridge)}')

 

#ridge model train score

np.round(ridge_model.score(extend_X_train, y_train),2)

 

#ridge model test score

np.round(ridge_model.score(extend_X_test, y_test),2)

 

# 일반모델 성능 점수

-lr 모델 extend X_test의 score: 0.87

-lr 모델 extend X_train의 score: 0.93

 ->잔차: 6

 

#lasso 모델 성능점수

-lasso model train score: 0.86

-lasso model test score 0.82

 ->잔차 4

 

#ridge 모델 성능점수

-ridge model train score: 0.92

-ridge model test score: 0.84

 ->잔차: 8

 

#Ridge 모델은 모델 정규화하기 전보다 과대적합이 오히려 더 증가함



    9. 하이퍼 파라미터 튜닝

1)Lasso 모델 하이퍼 파라미터 튜닝

  • 반복문을 사용하여 하이퍼 파라미터 튜닝

#lasso 모델 하이퍼 파라미터 튜닝

#alpha 값에 따라 RMSE 계산값을 빈 리스트에 담기

 

#alpha값 리스트

alpha_list=[0.001, 0.01, 0.1, 1, 10,100,1000]

 

#RMSE 결과값 저장할 리스트 생성

lasso_train_list=[]

lasso_test_list=[]

 

#반복문을 사용하여 lasso 모델 하이퍼 파라미터 튜닝

for i in alpha_list: #8번

  #모델 생성

  lasso_model=Lasso(alpha=i)

 

  #모델 학습

  lasso_model.fit(extend_X_train, y_train)

 

  #모델 예측(train)

  lasso_train_pre=lasso_model.predict(extend_X_train)

 

  #RMSE 계산(train)

  lasso_train_rmse=np.sqrt(mean_squared_error(lasso_train_pre, y_train))

 

  #lasso_train_list에 RMSE 값 넣기

  lasso_train_list.append(lasso_train_rmse)

 

  #모델 예측(test)

  lasso_test_pre=lasso_model.predict(extend_X_test)

 

  #RMSE 계산(test)

  lasso_test_rmse=np.sqrt(mean_squared_error(lasso_test_pre, y_test))

 

  #lasso_test_list에 RMSE 값 넣기

  lasso_test_list.append(lasso_test_rmse)

 

  • 하이퍼 파라미터 적용한 데이터를 시각화

#lasso 모델의 train/test의 RMSE 값을 그래프로 표현

import matplotlib.pyplot as plt

 

plt.figure(figsize=(10,7))

plt.plot(lasso_train_list, label='train') #train 그래프

plt.plot(lasso_test_list, label='test') #test 그래프

 

plt.title('Lasso Model: alpha / RMSE Graph') #그래프 제목

plt.xlabel('alpha') #x축 라벨

plt.ylabel('RMSE') #y축 라벨

plt.legend()

plt.grid() #격자 무늬

 

plt.show()

 

2)Ridge 모델 하이퍼 파라미터 튜닝

  • 반복문을 사용하여 하이퍼 파라미터 튜닝

#Ridge 모델 하이퍼 파라미터 튜닝

#alpha 값에 따라 RMSE 계산값을 빈 리스트에 담기

 

#alpha값 리스트

alpha_list=[0.001, 0.01, 0.1, 1, 10,100,1000]

 

#RMSE 결과값 저장할 리스트 생성

ridge_train_list=[]

ridge_test_list=[]

 

#반복문을 사용하여 Ridge 모델 하이퍼 파라미터 튜닝

for i in alpha_list: #8번

 

  #모델 생성

  ridge_model=Ridge(alpha=i)

 

  #모델 학습

  ridge_model.fit(extend_X_train, y_train)

 

  #모델 예측(train)

  ridge_train_pre=ridge_model.predict(extend_X_train)

 

  #RMSE 계산(train)

  ridge_train_rmse=np.sqrt(mean_squared_error(ridge_train_pre, y_train))

 

  #ridge_train_list에 RMSE 값 넣기

  ridge_train_list.append(ridge_train_rmse)

 

  #모델 예측(test)

  ridge_test_pre=ridge_model.predict(extend_X_test)

 

  #RMSE 계산(test)

  ridge_test_rmse=np.sqrt(mean_squared_error(ridge_test_pre, y_test))

 

  #ridge_test_list에 RMSE 값 넣기

  ridge_test_list.append(ridge_test_rmse)

 

  • 하이퍼 파라미터 적용한 데이터를 시각화

#Ridge 모델의 train/test의 RMSE 값을 그래프로 표현

 

import matplotlib.pyplot as plt

 

plt.figure(figsize=(10,7))

plt.plot(ridge_train_list, label='train') #train 그래프

plt.plot(ridge_test_list, label='test') #test 그래프

 

plt.title('Ridge Model: alpha / RMSE Graph') #그래프 제목

plt.xlabel('alpha') #x축 라벨

plt.ylabel('RMSE') #y축 라벨

 

plt.legend()

plt.grid()

 

plt.show()

 

#보스턴 주택 가격 데이터 하이퍼파라미터 튜닝 후

#Lasso모델이 Ridge모델보다 train 데이터와 test 데이터의 RMSE값의 차이가 적다->Lasso 모델이 과대적합 제어에 더 유리하다

 

3)ElasticNet 모델 하이퍼 파라미터 튜닝

  • alpha: 규제의 강도
  • l1_ratio: L1, L2 규제 비율

예)l1_ratio=0.5(L1 : L2=5:5) /0(L2 규제만 사용)/1(L1 규제만 사용)

# ElasticNet 모델 불러오기

 

from sklearn.linear_model import ElasticNet

#ElasticNet 모델 생성

 

#alpha: 규제의 강도

#l1_ratio: L1, L2 규제 비율

 

ela_model=ElasticNet(alpha=10, l1_ratio=0.5)

 

#ElasticNet 모델 학습

ela_model.fit(extend_X_train, y_train)

 

#ElasticNet 예측

ela_train_pre=ela_model.predict(extend_X_train)

ela_test_pre=ela_model.predict(extend_X_test)

 

#규제모델 적용 후 MSE, RMSE 계산

train_mse_ela=mean_squared_error(ela_train_pre, y_train)

test_mse_ela=mean_squared_error(ela_test_pre, y_test)

 

#MSE 값 확인

print(f'train 데이터 MSE 값: {train_mse_ela}')

print(f'test 데이터 MSE 값: {test_mse_ela}')

print(f'MES 잔차: {train_mse_ela-test_mse_ela}')

 

#RMSE 값 확인: np.sqrt(MSE)

print(f'train 데이터 RMSE 값: {np.sqrt(train_mse_ela)}')

print(f'test 데이터 RMSE 값: {np.sqrt(test_mse_ela)}')

print(f'RMSE 잔차: {np.sqrt(train_mse_ela)-np.sqrt(test_mse_ela)}')

 

#ElasticNet train 데이터 성능점수

np.round(ela_model.score(extend_X_train, y_train),2)

 

#ElasticNet test 데이터 성능점수

np.round(ela_model.score(extend_X_test, y_test),2)

 

## 일반모델 성능 점수

#lr 모델 extend X_test의 score: 0.87

#lr 모델 extend X_train의 score: 0.93

#->잔차: 6

 

 

## lasso 모델 성능점수

#lasso model train score: 0.86

#lasso model test score 0.82

#->잔차 4

 

## ridge 모델 성능점수

 

#ridge model train score: 0.92

#ridge model test score: 0.84

#->잔차: 8

 

 

## ElasticNet 모델 성능점수

#ElasticNet model train score: 0.87

#ElasticNet model train score: 0.81

#->잔차: 6


'머신러닝' 카테고리의 다른 글

[ML]13. 자연어 처리  (0) 2023.09.06
[ML]12. 로지스틱 회귀모델  (0) 2023.09.01
[ML]10. 선형회귀모델  (0) 2023.08.30
[ML]9. 분류평가지표  (0) 2023.08.29
[ML]8. 타이타닉호 생존자 예측 모델  (0) 2023.08.25