[Regression] Ridge and Lasso Regression in Python(1) - Polynomial


이번에는 Ridge와 Lasso Regression을 파이썬으로 구현해보도록 하겠습니다.


1. 데이터를 생성합니다.

그리고 모델의 복잡도를 비교하기 위해 x의 차수를 높혀가며 선형 회귀식을 만들어 보려고 합니다.

rcParams는 figure의 사이즈를 지정하기 위해 사용합니다.


import numpy as np
import pandas as pd
import random
from matplotlib.pylab import rcParams
rcParams['figure.figsize'] = 8, 5
from sklearn.linear_model import LinearRegression
import matplotlib.pyplot as plt

x = np.array([i*np.pi/180 for i in range(60, 300, 4)])
np.random.seed(10)
y = np.sin(x) + np.random.normal(0, 0.15, len(x))
data = pd.DataFrame(np.column_stack([x, y]), columns=['x', 'y'])
plt.plot(data['x'], data['y'], '.')
for i in range(2, 16): # power
colname = 'x_%d'%i #new var will be x_power
data[colname] = data['x']**i

만들어진 데이터는 가우시안 에러를 가진 사인 곡선입니다.


2. 모델의 차수 별 계수와 절편 값을 테이블로 만들기 위해 dataframe을 만듭니다.

#Initialize a dataframe to store the results:
col = ['rss','intercept'] + ['coef_x_%d'%i for i in range(1, 16)]
ind = ['model_pow_%d'%i for i in range(1, 16)]
coef_matrix_simple = pd.DataFrame(index=ind, columns=col)

#Define the powers for which a plot is required:
models_to_plot = {1:231,3:232,6:233,9:234,12:235,15:236}

models_to_plot은 1차는 2*3 grid의 첫번째, 3차는 grid의 두번째에 띄우기 위한 Dictionary 입니다.


3. Polynomial regression을 하기위해 linear_regression 함수를 만듭니다.

predictors는 몇개의 항(차수)를 사용할지 정하여 feature 명을 저장합니다.

linreg로 차수만큼 테이블의 컬럼과 데이터를 불러와서 피팅시킵니다.

그리고 다시 training 데이터를 넣어 모델 예측값을 구합니다.


rss는 예측과 실체값의 차이 즉 MSE 입니다.

def linear_regression(data, power, models_to_plot):
# initialize predictors:
predictors=['x']
if power >= 2:
predictors.extend(['x_%d'%i for i in range(2, power+1)])
#Fit the model
linreg = LinearRegression(normalize=True)
linreg.fit(data[predictors], data['y']) # 차수만큼 테이블의 컬럼을 불러와서 피팅시킨다.
y_pred = linreg.predict(data[predictors]) # ligreg 모델에 데이터를 넣었을때 나오는 y 값

#Check if a plot is to be made for the enterted power
if power in models_to_plot:
plt.subplot(models_to_plot[power])
plt.tight_layout() # plot과 window 여백 제거
plt.plot(data['x'], y_pred)
plt.plot(data['x'], data['y'], '.')
plt.title('Plot for power: %d' % power)

#Return the result in pre-defined format
rss = sum((y_pred - data['y'])**2)
ret = [rss]
ret.extend([linreg.intercept_])
ret.extend(linreg.coef_)
return ret

아래 코드를 실행시키면 coef_matrix가 채워집니다.

for i in range(1,16):
coef_matrix_simple.iloc[i-1, 0:i+2] = linear_regression(data, power=i, models_to_plot=models_to_plot)


아래는 결과값입니다. 15차까지 다 나오지는 않았지만 차수가 높아질 수록 계수의 절대값의 크기가 커지고 모델의 복잡도가 증가합니다.

Ridge와 Lasso를 사용하여 가중치 규제를 하는 이유가 이것입니다. 계수의 절대값이 점점 커지기 때문에 가중치 값을 줄이고 모델의 복잡도를 줄일 필요가 있습니다.

가중치가 크다는 말은 무엇일까요? 큰 가중치는 그 feature를 강조한다는 뜻입니다. 하지만 가중치가 점점 커지다 보면 모델이 training data에 모두 예측하려합니다.



따라서 차수가 높아질수록 과적합 현상이 일어납니다.



도움이 되셨다면 공감 부탁드려요!


+ Recent posts