ㅅㅇ

머신러닝 _ 13_02 선형회귀 _ 다항회귀 본문

AI_STUDY/머신러닝

머신러닝 _ 13_02 선형회귀 _ 다항회귀

SO__OS 2022. 7. 14. 19:15
플레이데이터 빅데이터캠프 공부 내용 _ 7/7 ~ 7/8

머신러닝 _ 13_02 선형회귀 _ 다항회귀

1. 다항회귀 개요  (Polynomial Regression)

:  단순한 직선형 보다 복잡한 비선형의 데이터셋을 학습하기 위한 방식.

 


1)   방법

 

각 Feature들을 거듭제곱한 것과 Feature들 끼리 곱한 새로운 특성들을 추가한 뒤 선형모델로 훈련시킨다.
    - 파라미터 가중치를 기준으로는 일차식이 되어 선형모델이다. 

      파라미터(Coef, weight)들을 기준으로는 N차식이 되어 비선형 데이터를 추론할 수 있는 모델이 된다.


      = >  `PolynomialFeatures` Transformer를 사용해서 변환한다.

 

 

2)  목적

 

 : Feature가 너무 적어 y의 값들을 다 표현 하지 못하여  = > underfitting이 되었기에  = >  Feature를 늘려준다.

 

- 오차  =  y 예측 ( = w*x + b ) - y 정답

 

- 데이터에 있는 잡음 때문에 항상 오차가 생길 수 밖에 없다. 그래서 회귀 모델의 경우엔 평가지표도 오차가 얼마나 났는지를 본다.
    - 이 잡음은 데이터를 잘 못 수집했거나, 우리가 y를 예측하는데 필요한 Feature 를 구하지 못했기 때문이다.

         - 즉, 성능이 안 나오는 것은 데이터 수집에서부터 이다. 


         - 그러나, 데이터 수집을 다시 하지 못하는 상황에서 이를 해결해야 한다.

             = = > 이때의 해결법이 다항회귀이다.

                       전처리 단계에서 기존의 수집한 feature 을 n 제곱하고 각 feature 끼리 곱해 새로운 feature를 만들어주는 것

                              - 파생변수를 무작정 만드는 게 아니라 기존의 feature 를 통해 관련있는 파생변수를 만드는 것.

 

 

2. 비선형 데이터 셋에서 다항회귀를 하지 않는다면 ?  - - 다항회귀를 해야 하는 이유

1) 데이터셋 만들기

 

y = X**2 + X + 2 

 

    >  X 와 y간의 패턴.  지금은 예시를 위해 데이터셋을 우리가 만들어 주었지만,  
    >  원래는 이 패턴을 우린 모르며,  이를 최대한으로 예측하는 것이 머신러닝 알고리즘 모델 학습의 목적이다.

    > 머신러닝 알고리즘은 우리가 만든 이 식을 예측할 수 있을까?
    > 결과를 먼저 말하자면,  선형 회귀 모델 X * w + b 로는 위 패턴 공식을 찾을 수 없다.

           x와 y에 대해 w과 b를 찾는 선형 회귀 모델은 X**2 항을 가진 함수를 예측할 수 없다.

 

 

import numpy as np
import pandas as pd
import matplotlib.pyplot as plt

np.random.seed(0)

# 데이터의 개수
m = 100

# X : feature
X = 6 * np.random.rand(m, 1) - 3  # 랜덤한 임의값 6 * (0~1 사이 실수 100개) - 3

# y : Target
y = X**2 + X + 2 + np.random.normal(0,1, size=(m,1)) # 인위적으로 잡음 Noise 만들어줌. 0과1 사이 랜덤

y = y.flatten() # 2차원 배열인 y를 1차원 배열로 만들어줌. (100,1) - > (100,)
print(X.shape, y.shape)
(100, 1) (100,)
 
 

 - 정답 데이터 : X  Feature 에 따른  y target 값 보기

# 이 그래프는 X feature가 하나라서 시각화할 수 있는 것.
# 3차원까지는 그릴 수 있겠지만, feature가 4개 부터는 우린 그래프로 표현할 수 없다.
plt.figure(figsize=(7,6))
plt.scatter(X, y, alpha=0.7)
plt.show()

 

2) 모델 생성 및 학습

 

from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score
from metrics import print_regression_metrics

lr = LinearRegression()
lr.fit(X, y) # => feature 1개 * coef_ + intercept_
print(lr.coef_, lr.intercept_) # 학습에서 최적의 coef_ , intercept_ 값을 찾고자 했다.

 

 

- 학습 결과  :   weight,   b 

 

    = >   0.78189543 * X + 5.175619278567209

[0.78189543] 5.175619278567209

 

 

3) train set 예측 및 평가

 

    R Square:0.19138252437306003   == >  성능 아주 안 좋다.

 

pred = lr.predict(X)
print_regression_metrics(y, pred)
MSE:7.729204760808937, RMSE:2.7801447373848966, R Square:0.19138252437306003

 

 

4) 새로운 데이터 셋 에 대해 예측 및 평가

 

     X_new = np.linspace(-3,3,100).reshape(-1, 1)

    

      ==>   X_new 셋에 대해 선형 회귀 모델이 예측한 pred_new 값은 실제와 오차가 큰 것을 볼 수 있다.  

               == >  선형 회귀 모델은 Feature 와 정답 y 간의 패턴 관계(W, b)를 제대로 찾지 못한 것이다.

 

X_new = np.linspace(-3,3,100).reshape(-1, 1)

pred_new = lr.predict(X_new) # -3 ~ 3 사이의 값들로 모델이 예측한 값들

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

plt.scatter(X, y, alpha=0.7) # 실제 데이터셋 - scatter plot
plt.plot(X_new, pred_new, color='red') # -3 ~ 3 값을 이용해 예측한 값들 - line plot

plt.grid(True)
plt.show()

 

3. PolynomialFeatures를 이용해 다항회귀구현

transformer(변환기)
    - 기존 Feature 에 N제곱한 Feature 들을 생성해주는 변환기

 

    - degree : 생성할 Feature 의 최고차항 차수를 지정. (  2  : X+X**2,     3  : x + x**2 + x**3 을 만든다. )

    - include_bias  :  상수항을 추가할 것인지 여부   (True: 모든값이 1인 Feature가 추가)

 

- 전처리시 PolynomialFeature 적용은 Dataset을 나누기(train,val,test) 전에 하든 후에 하든 상관없다.

 

1) PolynomialFeatures  생성

 

    - X_poly : 변환해준 Feature 들

 

       - 현재, feature 하나로 교차항은 없이 x, x**2 만 있따.

from sklearn.preprocessing import PolynomialFeatures

poly_f = PolynomialFeatures(degree=2, include_bias=False) 
X_poly = poly_f.fit_transform(X)

 

  - X_ploy shape 확인 : 변환해준 Feature 갯수 확인

X.shape, X_poly.shape # feature 2개
((100, 1), (100, 2))
 
 
 
-  각 feature 를 어떤 계산을 통해서 만들었는지 알려준다.  x ,  x**2
poly_f.get_feature_names_out()
array(['x0', 'x0^2'], dtype=object)
 

2) LinearRegression 모델 생성 및 학습   w, b 확인

 

lr2 = LinearRegression()
lr2.fit(X_poly, y)

print(lr2.coef_, lr2.intercept_)
[0.97906552 0.94978823] 2.340500756262887

 

3) 모델 예측 및 평가 (변환 전 후 비교)

  -  R2 가 1이면 다 맞춘건데 0.898  == > 성능이 확실하게 오른 것을 볼 수 있다.

 

pred2 = lr2.predict(X_poly)

print_regression_metrics(y, pred2, title="다항회귀")
print_regression_metrics(y, pred, title="변환없이")
 
 
다항회귀
MSE:0.9735576723414217, RMSE:0.9866902616026073, R Square:0.8981478985551461
변환없이
MSE:7.729204760808937, RMSE:2.7801447373848966, R Square:0.19138252437306003

 

 

4) 새로운 데이터 셋에 대해 예측 및 평가 시각화 (변환 전 후 비교)

 

     X_new = np.linspace(-3,3,100).reshape(-1, 1)

    

      ==>   X_new_poly 을 통해 선형 회귀 모델이 예측한 pred_new2 값은 실제와 오차가 작은 것을 볼 수 있다.  

               == >  선형 회귀 모델은 Feature 와 정답 y 간의 패턴 관계(W, b)를 어느 정도 잘 찾았다.

 

X_new = np.linspace(-3,3,100).reshape(-1, 1)
X_new_poly = poly_f.transform(X_new) # X_new 를 polynomialFeatures 전처리
pred_new2 = lr2.predict(X_new_poly) # 예측

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

plt.scatter(X, y) # 원래 데이터셋

# 변환후.
plt.plot(X_new, pred_new2, color='red', label = '변환후') # -3 ~ 3 사이의 값을 이용해서 추론한 결과

# 변환전. 과소적합. 데이터를 거의 찾지 못했다.
plt.plot(X_new, lr.predict(X_new), color = 'green', label = '변환전')

plt.grid(True)
plt.show()

 

3. 다항회귀이 일으킬 수 있는 문제점 

  : degree 를 너무 크게 잡으면,  Feature 의 수가 너무 많아 Overfitting 문제가 생긴다. (아래의 그래프)

     

      - feature 의 수를 늘려, 학습에서는 모든 trian 데이터셋에 최대한 맞추고 있다.
        근데 val 새로운 데이터가 들어갔을 때 
        학습할 데이터에 없었던 데이터에 대해 예측을 해야 한다면?  지금의 양끝에서처럼 큰 오차를 보일 것이다. 

           == > 오버피팅   ==> R Square:-1674022845.3905861

 

- 복잡한 모델이라고 무작정 PolynomialFeature 적용한 게 성능이 좋아지는 게 아니다.

 

MSE:16001219048.59061, RMSE:126495.92502760953, R Square:-1674022845.3905861

degree = 100 설정으로 feature의 수가 100일 때 예측 결과를 시각화        (그 외 설정 값들은 위의 예제와 같음.)

 

4. PolynomialFeatures 를 이용한 전처리는 언제 사용하는가? 

- LinearRegression 모델 기준 검증 결과,

 

     -  underfitting이 발생하면

        LinearRegression 모델을 좀 더 복잡한 모델로 만들어 줄 필요가 있다.

              = = > 그때는 feature 수를 늘려야 한다.  = = >  적용하는 전처리가 PolynomialFeatres


     -  그러나, Train data에 Feature 너무 많아 Overfitting이 발생한다면

         LinearRegression 모델이 너무 복잡한 모델이 된다.

              = = > 그때는 feature 수를 줄여야 한다.  = = >  이를 해결해주는 전처리가 규제

 

 

5. 규제 (Regularization)

선형 회귀 모델에서 과대적합(Overfitting) 문제를 해결하기 위해 

               가중치(회귀계수)에 페널티 값을 적용한다.

- 규제의 목적 : 입력데이터의 Feature들이 너무 많은 경우 Overfitting이 발생.
     - Feature수에 비해 관측치 수가 적은 경우 모델이 복잡해지면서 Overfitting이 발생한다.
    
    
- 해결


    1. 데이터를 더 수집한다. 
    2. Feature selection
        - 불필요한 Features들을 제거한다.


    3. 규제 (Regularization) 을 통해 Feature들에 곱해지는 가중치가 커지지 않도록 제한한다.

        == > 가중치 w를 0에 가까운 값으로 만들어 준다.


           1) L1 규제 (Lasso)   
           2)  L2 규제 (Ridge) 

 

 

5.1 Ridge Regression (L2규제)

 

- 손실함수(Loss Function)

                   : 모델의 예측한 값과 실제값 사이의 차이를 정의하는 함수로 모델이 학습할 때 사용된다

                   : 학습 중에 오차를 가장 적게하는 최적의 파라미터를 찾는 최적화 작업에서 '오차를 구하는 함수'

 

- 손실함수 loss function  에 아래의 규제항을 더해준다.

** 내부적으로 미분을 하는데 이차함수 미분이기에 1/2 를 붙여주는 것

  

  - 규제는 원래 생성한 오차 보다 크게 만들어주는 작업  (over 에서 train 성능이 좋아 이래도 상관없) 
          =>  오차를 학습할 때 키워버리면   오차를 줄이기 위해      weight 를 줄이는 방향 ↓   으로 갈 것이다.

 

 

  - 하이퍼 파라미터 ∝ :  모델을 얼마나 많이 규제할지 우리가 조절하는 값

 

     - ∝= 0 에 가까울수록 규제가 약해진다. (0일 경우 선형 회귀. 규제 없는.)


     - ∝ 가 커질수록 오차가 커지게 되어, 학습에서 모든 가중치 weight 들이 작아지게 되므로 

        입력데이터의 Feature들 중 중요하지 않은 Feature의 예측에 대한 영향력이 작아지게 된다. = > Feature 규제

 

 

5.1.1 규제 기본 예제

 

# boston 데이터 셋

 

1)  데이터 로딩, 분리, StandardScaler 전처리

 

from sklearn.datasets import load_boston
from sklearn.preprocessing import StandardScaler

data = load_boston()
X, y = data['data'], data['target']
X_train, X_test, y_train, y_test = train_test_split(X, y, random_state=0)

scaler = StandardScaler()
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled = scaler.transform(X_test)

 


 2) L2규제를 적용한 Linear Regression 모델 객체 생성, 학습, 추론  :   alpha: 1.0 (기본값)

 

# L2규제를 적용한 Linear Regression 모델
from sklearn.linear_model import Ridge 

# 객체 생성
ridge1 = Ridge(random_state=0) # alpha: 1.0(기본) - 규제항의 값을 조절하는 규제하이퍼파라미터
# 학습
ridge1.fit(X_train_scaled, y_train)
# 추론
pred_train1 = ridge1.predict(X_train_scaled)
pred_test1 = ridge1.predict(X_test_scaled)

 

- 평가

# alpha = 1 
print('alpha=1')
print_regression_metrics(y_train, pred_train1, title='Train')
print_regression_metrics(y_test, pred_test1, title="Test")

# 알파 값이 작아, 기존 규제 전 Train 과 비교했을 때 별차이가 없다.
MSE:19.640519427908046, RMSE:4.4317625644779355, R Square:0.7697699488741149
alpha=1
Train
MSE:19.641949353818962, RMSE:4.43192388854084, R Square:0.7697531869999299
Test
MSE:29.853763334547615, RMSE:5.463859746968952, R Square:0.6345884564889053

 

 

3) L2규제를 적용한 Linear Regression 모델 객체 생성, 학습, 추론  :   alpha: 100  규제 강도를 너무 크게 한다면?

 

alpah=100   == > 알파를 1.0 했을 때에 비해 규제를 너무 크게 하여  underfitting 발생 

                     == > 오히려, 너무 단순한 모델이 되어 성능이 떨어짐.

 

from sklearn.linear_model import Ridge
ridge1 = Ridge(alpha=1000, random_state=0) #alpah=100 
ridge1.fit(X_train_scaled, y_train)
pred_train1 = ridge1.predict(X_train_scaled)
pred_test1 = ridge1.predict(X_test_scaled)

 

print('alpha=1000')
print_regression_metrics(y_train, pred_train1, title='Train')
print_regression_metrics(y_test, pred_test1, title="Test")
alpha=1000
Train
MSE:37.6379127019148, RMSE:6.13497454778052, R Square:0.5588009473252299
Test
MSE:47.385118128796044, RMSE:6.883684923701552, R Square:0.42000380451661745

 

 

- weight 값들 : 알파를 1.0 했을 때의 weight와 비교해서 전체적으로 0에 가깝게 weight가 작아진 것을 볼 수 있다.

 

ridge1.coef_
array([-0.44267768,  0.38220219, -0.51288178,  0.3335525 , -0.37129939,
        1.25386598, -0.32729508, -0.06287806, -0.28302417, -0.47738562,
       -0.87977916,  0.4225767 , -1.16283877])

 

 

5.1.2 GridSearchCV를 이용해 최적의 alpha 탐색

 

from sklearn.model_selection import GridSearchCV
from sklearn.linear_model import Ridge

param = {"alpha":[0.01, 0.1, 1, 5, 10, 20, 30, 40, 100]} # 넣어줄 알파값
ridge = Ridge(random_state=0) # L2규제를 적용한 Linear Regression 모델 객체 

# gs 객체. R square, MSE 평가 - r2 기준
gs = GridSearchCV(ridge, param, cv=4, scoring=['r2', 'neg_mean_squared_error'], refit='r2') 

gs.fit(X_train_scaled, y_train)

 

- gs.cv_results_ 확인

result_df = pd.DataFrame(gs.cv_results_)
result_df.sort_values('rank_test_r2').head()

 

 

 

5.1.3 규제 alpha 에 따른 weight 변화

 

 == > alpha 가 커질 수록 weigth 값이 0 에 가까워지는 것을 볼 수 있다.

 

import matplotlib.pyplot as plt
np.random.seed(1)

alpha_list = [0,  1, 10, 100,500,1000]
coef_df = pd.DataFrame()

plt.figure(figsize=(6,25))

# alpha 값 넣어주는 반복문
for idx, alpha in enumerate(alpha_list, start=1):

    ridge = Ridge(alpha=alpha)
    ridge.fit(X_train_scaled, y_train)
    
    pred_train = ridge.predict(X_train_scaled)
    pred_test = ridge.predict(X_test_scaled)

    # 각 feature(컬럼)들에 곱해지는 weight 들을 반올림해서 각 컬럼명으로 Series 만들기
    w = pd.Series(np.round(ridge.coef_,3), index=data["feature_names"])
   
    # 만든 weight series를 DataFrame에 각 설정해준 alpha 이름으로 추가
    coef_df[f'alpha {alpha}'] = w.copy() 
    
    w = w.sort_values() # 정렬하여
    
    # weight 그래프로 출력
    plt.subplot(7,1,idx)
    
    # 각 feature 별 weight
    plt.bar(x=w.index, height=w) # x = 각 컬럼명, y = 각 컬럼에 따른 weight 들
    plt.xticks(rotation=45)
    plt.ylim(-20, 20)
    plt.title(f"alpha {alpha}") # 각 설정해준 alpha 
    plt.grid(True)

plt.tight_layout()
plt.show()

 

 

- 데이터 프레임으로 weigth 값 확인 

 

 

 

5.2 Lasso(Least Absolut Shrinkage and Selection Operator) Regression (L1 규제)

 

- 손실함수에 아래의 규제항을  더한다.

- Lasso 회귀의 상대적으로 덜 중요한 특성의 가중치를 0으로 만들어 자동으로 Feature Selection이 된다.

 

- 하이퍼 파라미터 alpah : 규제 강도를 설정(기본: 1.0)

       - 클수록 강한 규제  == >  더 단순한 모델을 만든다.  

 

 

5.1.1 규제 기본 예제

 

# boston 데이터 셋 - 위 예제에서 데이터 로딩, 분리, StandardScaler 전처리 한 것으로

 

 

- L1 규제를 적용한 Linear Regression 모델  :   alpha: 1.0 (기본값)

lasso = Lasso(random_state=0) #alpha: 1.0
lasso.fit(X_train_scaled, y_train)
pred_train = lasso.predict(X_train_scaled)
pred_test = lasso.predict(X_test_scaled)

print('alpha=1')
print_regression_metrics(y_train, pred_train, "alpha=1 Train")
print_regression_metrics(y_test, pred_test, "alpha=1 Test")

 

- 규제로 인하여 단순화된 모델이 되었다.

alpha=1
alpha=1 Train
MSE:25.38793844433231, RMSE:5.038644504659196, R Square:0.702397567056503
alpha=1 Test
MSE:35.48963616828034, RMSE:5.957317866983458, R Square:0.5656050935497574

 

 

-  weigth 값이 0 에 가까워진 것을 확인 할 수 있다.

lasso.coef_
array([-0.        ,  0.        , -0.        ,  0.        , -0.        ,
        2.52933025, -0.        , -0.        , -0.        , -0.22763148,
       -1.70088382,  0.13186059, -3.60565498])

 

 

 

5.2.2 규제 alpha 에 따른 weight 변화

 

- L1 규제를 적용한 Linear Regression 모델  :  alpha_list = [0, 0.1, 0.5, 1, 5, 10]

 

import matplotlib.pyplot as plt
alpha_list = [0, 0.1, 0.5, 1, 5, 10]

lasso_coef_df = pd.DataFrame()

plt.figure(figsize=(7,25))
for idx, alpha in enumerate(alpha_list, start=1):
    lasso = Lasso(alpha=alpha, random_state=0)
    lasso.fit(X_train_scaled, y_train)
    
    w = pd.Series(lasso.coef_, index=data["feature_names"])
    lasso_coef_df[f'alpha {alpha}'] = w
    
    # weight 들을 막대그래프로 시각화
    w = w.copy().sort_values()
    plt.subplot(6,1,idx)
    
    plt.bar(x=w.index, height=w)
    plt.xticks(rotation=45)
    plt.ylim(-20, 20)
    plt.grid(True)
    plt.title(f"Lasso alpha {alpha}")
    
plt.tight_layout()
plt.show()

 

 

- alpha = 10 일 때, weight 값은 모두 0 이다.  == > underfitting

 

lasso_coef_df

 

6.  PolynomialFeatures로 전처리한 Boston Dataset에 Ridge, Lasso  규제 적용

 

#  degree 2로 PolynomialFeatures 전처리한 데이터셋 이용

X_train_scaled_poly.shape
(379, 119)

 

1)  규제 안 했을 때 - PolynomialFeatures 전처리한 데이터셋  LinearRegression으로 평가

 
from sklearn.linear_model import Ridge, Lasso, LinearRegression

# 생성
lr = LinearRegression()
# 학습
lr.fit(X_train_scaled_poly, y_train)
# 추론
pred_train_lr = lr.predict(X_train_scaled_poly)
pred_test_lr = lr.predict(X_test_scaled_poly)
# 평가
print_regression_metrics(y_train, pred_train_lr, title="LinearRegression Train")
print_regression_metrics(y_test, pred_test_lr, title="LinearRegression Test")
LinearRegression Train
MSE:4.091369291723247, RMSE:2.022713348876515, R Square:0.9520401604109383
LinearRegression Test
MSE:31.990455686689362, RMSE:5.656010580496589, R Square:0.6084352361509877

 

 

2) L2 규제 : Ridge 의 alpha값 변화에 따른 R square 확인

 

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

# alpha 별 R square값들을 저장할 리스트
ridge_train_metrics_list = []
ridge_test_metrics_list = []

for alpha in alpha_list:
    # 객체 생성
    ridge = Ridge(alpha=alpha, random_state=0)
    
    # 학습 - poly 전처리한 X_train 값과 정답 y_train 으로
    ridge.fit(X_train_scaled_poly, y_train)
    
    # 추론 - X_train_scaled_poly, X_test_scaled_poly
    pred_train = ridge.predict(X_train_scaled_poly)
    pred_test = ridge.predict(X_test_scaled_poly)
    
    # 평가(r2) - 평가결과를 List에 append
    ridge_train_metrics_list.append(r2_score(y_train, pred_train))
    ridge_test_metrics_list.append(r2_score(y_test, pred_test))

 

 

- train set 과 test set 에 대한 r2 평가 결과 를 데이터프레임으로 보기

 

     == > alpha 값이 커져 규제가 심해지는 만큼 모델은 단순화 되어 train 성능은 떨어지지만 test 성능은 오르고 있다.

 

ridge_result = pd.DataFrame({
    "alpha":alpha_list,
    "train":ridge_train_metrics_list,
    "test":ridge_test_metrics_list
})

ridge_result

 

 

3) L1 규제 : lasso 의 alpha값 변화에 따른 R square 확인

 

alpha_list = [0.08, 0.1, 0.2, 0.3, 0.4, 0.5]

# 평가결과를 저장할 리스트
lasso_train_metrics_list = []
lasso_test_metrics_list = []

for alpha in alpha_list:
#     모델 생성
    lasso = Lasso(alpha=alpha, random_state=0)
#     학습
    lasso.fit(X_train_scaled_poly, y_train)
#     추론
    pred_train = lasso.predict(X_train_scaled_poly)
    pred_test = lasso.predict(X_test_scaled_poly)
#     평가 - 평가결과를 list에 추가
    lasso_train_metrics_list.append(r2_score(y_train, pred_train))
    lasso_test_metrics_list.append(r2_score(y_test, pred_test))

 

- train set 과 test set 에 대한 r2 평가 결과 를 데이터프레임으로 보기

 

     == > alpha 값이 커져 규제가 심해지는 만큼 모델은 단순화 되어 train 성능은 떨어지고 있다.

     == > test 셋 성능은 또한 단순화로 떨어지는데, 모델에 따라 다르지만 0.7 이상 정도면 좋게보고

             train 셋 과 test 셋의 성능 차이가 덜 나는 0.1 일 때가 성능을 가장 좋게 본다.

 

 

7. ElasticNet(엘라스틱넷)

릿지와 라쏘를 절충한 모델.


규제항에 릿지, 라쏘 규제항을 더해서 추가한다. 

 

- 혼합비율 r을 사용해 혼합정도를 조절   ( r 는 Lassa(L1규제) 쪽 비율 )    
      == >    r=0 이면 릿지와 같고 r=1 이면 라쏘와 같다.

 

-   alpha : 패탈티(규제강도) ,    l1_ratio = r  비율 설정

 

from sklearn.linear_model import ElasticNet

# 모델 생성
elastic = ElasticNet(alpha=0.1, l1_ratio=0.6) # alpha :페날티(규제강도), l1_ratio: 비율(라쏘쪽. 위의것으로 보면 앞의것의 r 지정.)
# 학습
elastic.fit(X_train_scaled, y_train)
# 추론
pred_train = elastic.predict(X_train_scaled)
pred_test = elastic.predict(X_test_scaled)
# 평가
print_regression_metrics(y_train, pred_train, title='ElasticNet alpha 0.1: Train')
print_regression_metrics(y_test, pred_test, title="ElasticNet alpha 0.1: Trest")

 

ElasticNet alpha 0.1: Train
MSE:20.128961453751398, RMSE:4.486531115879104, R Square:0.7640443348955887
ElasticNet alpha 0.1: Trest
MSE:31.441232021951834, RMSE:5.607248168393462, R Square:0.6151577610405823

 

 

[정리]

 

단순 <--------------------------------- 선형 회귀 ------------------------------> 복잡
under                                                                                                over
Feature 늘려주기                                                                              Feature 줄여주기
PolynomialFeatures 전처리                                                            R 규제 (L2, L1, ElasticNet)

 

 

일반적으로 선형회귀의 경우 어느정도 규제가 있는 경우가 성능이 좋다.


- 보통, 기본적으로 Ridge를 사용한다.


- Target에 영향을 주는 Feature가 몇 개뿐일 경우 특성의 가중치를 0으로 만들어 주는 Lasso 사용한다. 


- 특성 수가 학습 샘플 수 보다 많거나 feature간에 연관성이 높을 때는 ElasticNet 을 사용한다.