OkBublewrap

회귀분석(4) 본문

Python/학습용

회귀분석(4)

옥뽁뽁 2022. 11. 21. 23:45

Ridge, Lasso, ElasticNet

회귀분석을 할 때 mse을 줄이는 데 집중하면 모델이 복잡해지고 과대적합의 우려가 있다. 복잡도를 줄이기 위해서는 독립변수를 줄이거나, 회귀계수를 규제하는 방법이 있다. Ridge, Lasso, ElasticNet은 회귀계수를 규제하는 방법이다. 

 

Ridge의 비용함수(L2)

 

$$ J(w) = MSE(w) + a\frac{1}{2}\sum_{i=1}^{n}w_{i}^{2} $$

 

비용함수를 줄이기 위해서는 mse도 줄여야하고 회귀계수인 w의 크기도 줄여야한다.

 

# Ridge
from sklearn.linear_model import Ridge
from sklearn.model_selection import cross_val_score

boston = load_boston()
bostonDF = pd.DataFrame(boston.data , columns = boston.feature_names)

bostonDF['PRICE'] = boston.target
print('Boston 데이타셋 크기 :',bostonDF.shape)

y_target = bostonDF['PRICE']
X_data = bostonDF.drop(['PRICE'],axis=1,inplace=False)

ridge = Ridge(alpha = 10)
neg_mse_scores = cross_val_score(ridge, X_data, y_target, scoring="neg_mean_squared_error", cv = 5)
rmse_scores  = np.sqrt(-1 * neg_mse_scores)
avg_rmse = np.mean(rmse_scores)
print(' 5 folds 의 개별 Negative MSE scores: ', np.round(neg_mse_scores, 3))
print(' 5 folds 의 개별 RMSE scores : ', np.round(rmse_scores,3))
print(' 5 folds 의 평균 RMSE : {0:.3f} '.format(avg_rmse))

sklearn의 boston 집 값 데이터를 ridge로 낼 것이다. a는 10으로 지정하고 교차검증을 진행을 한다.

Boston 데이타셋 크기 : (506, 14)

5 folds 의 개별 Negative MSE scores: [-11.422 -24.294 -28.144 -74.599 -28.517]

5 folds 의 개별 RMSE scores : [3.38 4.929 5.305 8.637 5.34 ] 5 folds 의 평균 RMSE : 5.518

 

alphas = [0 , 0.1 , 1 , 10 , 100]

for alpha in alphas :
    ridge = Ridge(alpha = alpha)
    
    #cross_val_score를 이용하여 5 fold의 평균 RMSE 계산
    neg_mse_scores = cross_val_score(ridge, X_data, y_target, scoring="neg_mean_squared_error", cv = 5)
    avg_rmse = np.mean(np.sqrt(-1 * neg_mse_scores))
    print('alpha {0} 일 때 5 folds 의 평균 RMSE : {1:.3f} '.format(alpha,avg_rmse))

알파 값을 0, 0.1, 1, 10, 100 순서대로 변경하면서 측정

alpha 0 일 때 5 folds 의 평균 RMSE : 5.829

alpha 0.1 일 때 5 folds 의 평균 RMSE : 5.788

alpha 1 일 때 5 folds 의 평균 RMSE : 5.653

alpha 10 일 때 5 folds 의 평균 RMSE : 5.518

alpha 100 일 때 5 folds 의 평균 RMSE : 5.330

 

알파가 증가할 수록 평균 rmse는 점점 줄어드는 것을 알 수 가 있다.

fig , axs = plt.subplots(figsize=(18,6) , nrows=1 , ncols=5)
coeff_df = pd.DataFrame()

# alphas 리스트 값을 차례로 입력해 회귀 계수 값 시각화 및 데이터 저장. pos는 axis의 위치 지정
for pos , alpha in enumerate(alphas) :
    ridge = Ridge(alpha = alpha)
    ridge.fit(X_data , y_target)
    # alpha에 따른 피처별 회귀 계수를 Series로 변환하고 이를 DataFrame의 컬럼으로 추가.  
    coeff = pd.Series(data=ridge.coef_ , index=X_data.columns )
    colname='alpha:'+str(alpha)
    coeff_df[colname] = coeff
    # 막대 그래프로 각 alpha 값에서의 회귀 계수를 시각화. 회귀 계수값이 높은 순으로 표현
    coeff = coeff.sort_values(ascending=False)
    axs[pos].set_title(colname)
    axs[pos].set_xlim(-3,6)
    sns.barplot(x=coeff.values , y=coeff.index, ax=axs[pos])

plt.show()

a에 따라 회귀계수값 시각화

a 값이 커질수록 회귀계수가 줄어드는 것을 볼 수 가 있다.

 

Lasso의 비용함수(L1)

$$J(w) = MSE(w) + a\sum_{i=1}^{n}\left|w_{i} \right|$$

# 라쏘에 사용될 alpha 파라미터의 값들을 정의하고 get_linear_reg_eval() 함수 호출
lasso_alphas = [ 0.07, 0.1, 0.5, 1, 3]
coeff_lasso_df =get_linear_reg_eval('Lasso', params=lasso_alphas, X_data_n=X_data, y_target_n=y_target)

alpha 0.07일 때 5 폴드 세트의 평균 RMSE: 5.612

alpha 0.1일 때 5 폴드 세트의 평균 RMSE: 5.615

alpha 0.5일 때 5 폴드 세트의 평균 RMSE: 5.669

alpha 1일 때 5 폴드 세트의 평균 RMSE: 5.776

alpha 3일 때 5 폴드 세트의 평균 RMSE: 6.189

 

Ridge와 반대로 a가 커질수록 rmse가 커진다. 

 

ElasticNet의 비용함수

$$ J(w) = MSE(w) +ra\sum_{i=1}^{n}\left|w_{i} \right| +\frac{1-r}{2}a\sum_{i=1}^{n} w_{i}^{2} $$

엘라스틱넷은 L1 + L2 혼합 함수이다.

# 엘라스틱넷에 사용될 alpha 파라미터의 값들을 정의하고 get_linear_reg_eval() 함수 호출
# l1_ratio는 0.7로 고정
elastic_alphas = [ 0.07, 0.1, 0.5, 1, 3]
coeff_elastic_df =get_linear_reg_eval('ElasticNet', params=elastic_alphas,
                                      X_data_n=X_data, y_target_n=y_target)

alpha 0.07일 때 5 폴드 세트의 평균 RMSE: 5.542

alpha 0.1일 때 5 폴드 세트의 평균 RMSE: 5.526

alpha 0.5일 때 5 폴드 세트의 평균RMSE: 5.467

alpha 1일 때 5 폴드 세트의 평균 RMSE: 5.597

alpha 3일 때 5 폴드 세트의 평균 RMSE: 6.068

'Python > 학습용' 카테고리의 다른 글

주성분분석(PCA)  (0) 2022.12.06
로지스틱 회귀분석  (0) 2022.12.04
회귀분석(3)  (0) 2022.11.21
회귀분석(2)  (0) 2022.11.10
회귀분석(1)  (0) 2022.11.10