본문 바로가기
데이터 분석/데이터 분석

[데이터 분석] Ridge 회귀 분석

by thomasito 2021. 7. 14.
반응형

 일반적으로 선형회귀 분석은 오차가 최소가 되는 최소자승법을 사용하여 회귀분석을 시행한다. 다만 이렇게 오차를 최소화하는데만 초점을 맞추면 훈련 데이터에 과최적화되어 오히려 실제 데이터를 예측하는 예측력이 굉장히 낮아지게 된다.(연애를 책으로만 배운 경우라고나 할까?^^) 따라서 이렇게 오차항을 최소화 하는 함수에 alpha 값으로 패널티를 부여하여 회귀 계수 값의 크기를 감소시켜 과최적화 문제를 개선하는 방식을 규제(Regularization)이라고 부른다.  

 

Ridge 회귀

 규제는 2 가지로 분류되는데 [패널티 = alpha * W] 계산시 W의 제곱에 대해 패널티를 부여하는 방식을 L2 규제라고 하며, W의 절대값에 패널티를 부여하는 방식을 L1 규제라고 한다. Ridge 릿지 회귀는 L2 규제 계수를 활용하는 회귀분석에 해당한다. Ridge 클래스의 주요 생성 파라미터는 alpha 이다. alpha 값의 변동에 따라 RMSE와 회귀계수가 어떻게 변하는 지 관찰해보자

import numpy as np
import matplotlib.pyplot as plt
import pandas as pd
import seaborn as sns
from scipy import stats
from sklearn.datasets import load_boston
%matplotlib inline

boston = load_boston()

# 데이터 세트 DF 로 변환 (데이터 입력, 컬럼 입력)
boston_df = pd.DataFrame(boston.data, columns = boston.feature_names)
print(boston.feature_names)

boston_df['PRICE'] = boston.target
print('Boston 데이터 세트 크기:', boston_df.shape)
boston_df.head()

from sklearn.model_selection import train_test_split
from sklearn.linear_model import LinearRegression
from sklearn.metrics import mean_squared_error, r2_score

# y 에 타겟데이터도 PRICE 넣음
# X 에 PRICE 컬럼(axis=1) 제외하고 넣음
y_target = boston_df['PRICE']
X_data = boston_df.drop(['PRICE'], axis=1, inplace=False)

# train_test_split(X값,Y값,테스트 데이터 비중)
X_train, X_test, y_train, y_test = train_test_split(X_data, y_target, test_size = 0.3,
                                                   random_state = 156)

 선형 회귀 시간에 다루었던 것처럼 보스턴 주택가격 데이터를 가져오고 X, y 의 훈련, 테스트 데이터를 분류한다.

 

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

# alpha = 10 으로 설정해 릿지회귀 수행
ridge = Ridge(alpha = 10)
neg_mse_scores = cross_val_score(ridge, X_data, y_target, scoring="neg_mean_squared_error", cv=5)
print(neg_mse_scores)

rmse_scores = np.sqrt(-1 * neg_mse_scores)
avg_rmse = np.mean(rmse_scores)
print(rmse_scores, avg_rmse)
print('5 folds 의 평균 RMSE(규제있음):{0:.3f}'.format(avg_rmse))

 alpha = 10 이라고 가정하고 Ridge 회귀를 학습시킨 후, cross_val_score을 활용하여 검증해보자. RMSE를 계산하기 위해서는 음의 MSE의 값을 구하여 (-)를 붙여 부호를 바꿔준 후 합계를 구해 루트를 씌워주면 된다. 실제 5 folds 의 평균값은 5.5로 계산되었으며, 일반 선형회귀 모델보다 오차가 더 적게 계산되었다.

 

 다음은 alpha 값을 증가시켜보면서 RMSE 가 어떻게 변동되는지 살펴보도록 하자.

# alpha 값의 변화에 따라 RMSE 값과 각 피처의 회귀계수를 시각화하고 DataFrame에 저장하는 예제

alphas = [0, 0.1, 1, 10, 100, 1000, 10000, 100000]

# alpha list 값을 반복하면서 alpha 에 따른 평균 rmse를 구함

for alpha in alphas:

	# alpha 값들이 for문을 돌면서 새로운 ridge 회귀 객체를 생성
    ridge = Ridge(alpha = alpha)
    
    # cross_val_score를 이용해 5 폴드의 평균 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))
    
    # alpha 값의 가정에 따라 평균 5 folds의 RMSE가 어떻게 계산되는지 출력
    print('alpha {0}일때 5 folds의 평균 RMSE: {1:.3f}'.format(alpha,avg_rmse))

 결과를 보면 alpha 값이 늘어날 수록 RMSE는 개선되는 것으로 나타난다. 다만 alpha 가 10000, 100000 으로 극단적으로 커질 수록 RMSE 값은 다시 증가하는 것을 확인할 수 있다. 이는 적당한 선에서 최적의 alpha 값을 찾는 것이 중요하다는 것을 나타낸다. 다음은 회귀계수를 보자.

 

# 각 alpha에 따른 회귀 계수 값을 시각화하기 위해 7개의 열로 된 맷플롯립 축 생성
fig, axs = plt.subplots(figsize=(18,6), nrows=1, ncols=8)

coeff_df = pd.DataFrame()

# 각 alpha 리스트 값을 차례로 입력해 회귀 계수 값 시각화 및 데이터 저장.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])
    
# for 문 바깥에서 맷플롯립의 show 호출 및 alpha 에 따른 피처별 회귀계수를 DataFrame으로 표시
# alpha 값을 증가시킬 수록 회귀계수는 계속 해서 작아지고 있음

 for 문을 돌리면서 alpha 값을 하나씩 넣어보면 회귀계수가 작아지는 것을 관찰할 수 있다.

 

ridge_alphas = [0, 0.1, 1, 10, 100, 1000, 10000, 100000]
sort_column = 'alpha:' + str(ridge_alphas[0])
coeff_df.sort_values(by=sort_column, ascending=False)

 숫자로 봐도 alpha 값의 증가에 따라 회귀계수가 비현실적으로 계속 작아지는 것을 볼 수 있다. RMSE 가 최소인 alpha=100의 경우에 회귀계수들이 적합해 보인다. 결론적으로 규제를 너무 많이 가할 수록 회귀 계수들이 너무 미미해져 예측력이 거의 없으므로 최적의 alpha 값을 찾는 것이 중요하다.

 

※ 포스팅한 내용은 머신러닝의 훌륭한 책인 <파이썬 머신러닝 완벽가이드>를 많이 참고하여 작성하였습니다.

반응형

댓글