정규화: OLS 모델을 과적합하지 마십시오!

6091 단어

소개



오늘 블로그에서는 기계 학습을 위한 정규화에 대해 살펴보겠습니다. 특히 L1 및 L2 정규화는 Lasso 및 Ridge 정규화라고도 합니다.

정규화는 더 나은 결과를 생성하기 위해 모델에서 과대적합에 페널티를 주는 데 사용되는 방법입니다. Lasso 및 Ridge 회귀의 경우 손실 함수에 페널티를 부여하기 위해 페널티 추정을 사용하고 있으며 이는 또 다른 추가 보너스인 기능 감소를 제공합니다. 이러한 기술은 수행하는 작업이 매우 유사하지만 페널티 기간 또는 정규화 요소의 약간의 조정을 통해 수행 방법이 다릅니다.

올가미





이 함수의 마지막 요소(정규화 요소)를 살펴보면 계수 크기의 절대값이 있습니다.


이것이 하는 일은 계수의 크기를 제한하고 어떤 경우에는 계수를 0으로 줄이거나 다른 말로는 특성을 모두 함께 제거하는 것입니다. 이 감소는 기능이 많은 경우 Lasso를 매우 유용하게 만듭니다.

산등성이





비교적 여기에 Ridge에 대한 비용 함수가 있습니다. 다시 정규화 요소를 살펴보겠습니다. 계수 크기의 절대값을 갖는 대신에 제곱되는 것을 볼 수 있습니다.


이 사례는 실제로 변수가 서로 상관될 때 더 나은 결과를 제공하기 위해 개발되었습니다. Ridge의 단점은 기능 수를 줄이는 기능이 있다는 것입니다.

예시



먼저 사용할 데이터 세트와 라이브러리를 가져오겠습니다.

import pandas as pd
import numpy as np
from sklearn import metrics 
import matplotlib.pyplot as plt
from sklearn.datasets import load_wine
from sklearn.linear_model import Lasso
from sklearn.linear_model import Ridge
from sklearn.linear_model import LinearRegression
from sklearn.model_selection import train_test_split
from sklearn.metrics import mean_squared_error, mean_squared_log_error 

이제 개인적으로 pandas로 데이터 세트를 보는 것을 좋아하므로 변환하겠습니다.

wine = load_wine()
data = pd.DataFrame(data= np.c_[wine['data'], wine['target']],
                     columns= wine['feature_names'] + ['target'])



선형 회귀



데이터를 일반 선형 회귀 모델에 맞추면 이 데이터로 이미 매우 우수한 성능을 가지고 있음을 알 수 있지만 일부 정규화로 무엇을 할 수 있는지 살펴보겠습니다.

linreg = LinearRegression()
linreg.fit(Xtrain, ytrain)

ypred = linreg.predict(Xtest)

print('Training r^2:', linreg.score(Xtrain, ytrain))
print('Test r^2:', linreg.score(Xtest, ytest))
print('Training MSE:', mean_squared_error(ytrain, linreg.predict(Xtrain)))
print('Test MSE:', mean_squared_error(ytest, linreg.predict(Xtest)))



올가미



lasso = Lasso(alpha=.0029) # Lasso is also known as the L1 norm 
lasso.fit(Xtrain, ytrain)

print('Training r^2:', lasso.score(Xtrain, ytrain))
print('Test r^2:', lasso.score(Xtest, ytest))
print('Training MSE:', mean_squared_error(ytrain, lasso.predict(Xtrain)))
print('Test MSE:', mean_squared_error(ytest, lasso.predict(Xtest)))



산등성이



ridge = Ridge(alpha=1.151) # Ridge is also known as the L2 norm
ridge.fit(Xtrain, ytrain)

print('Training r^2:', ridge.score(Xtrain, ytrain))
print('Test r^2:', ridge.score(Xtest, ytest))
print('Training MSE:', mean_squared_error(ytrain, ridge.predict(Xtrain)))
print('Test MSE:', mean_squared_error(ytest, ridge.predict(Xtest)))



람다 값 찾기



정규화 사용의 중요한 부분은 람다 값을 설정하는 것입니다. 람다 값을 너무 크게 선택하면 모델이 과소적합되고, 람다 값이 낮을수록 모델이 선형 회귀를 사용하는 데 가까워지고 0은 선형 회귀 모델이 됩니다.

따라서 가장 좋은 방법은 모델이 다른 값으로 얻는 오류를 그래프로 표시하는 것입니다.

train_mse = []
test_mse = []
alphas = []

for alpha in np.linspace(0, 10, num=1000):
    ridge = Ridge(alpha=alpha)
    ridge.fit(Xtrain, ytrain)

    train_preds = ridge.predict(Xtrain)
    train_mse.append(mean_squared_error(ytrain, train_preds))

    test_preds = ridge.predict(Xtest)
    test_mse.append(mean_squared_error(ytest, test_preds))

    alphas.append(alpha)



fig, ax = plt.subplots()
ax.plot(alphas, train_mse, label='Train')
ax.plot(alphas, test_mse, label='Test')
ax.set_xlabel('Alpha')
ax.set_ylabel('MSE')

# np.argmin() returns the index of the minimum value in a list
optimal_alpha = alphas[np.argmin(test_mse)]

# Add a vertical line where the test MSE is minimized
ax.axvline(optimal_alpha, color='black', linestyle='--')
ax.legend();

print(f'Optimal Alpha Value: {float(optimal_alpha)}')

이제 그래프에서 우리는 테스트 오류가 가장 낮아 과적합과 과소적합 사이의 균형을 제공하는 람다에 대한 최적의 지점이 있음을 알 수 있습니다!



결론



회귀는 특히 많은 수의 기능이 있는 경우 과적합을 처리하는 좋은 방법입니다. 내가 제공한 예에서는 좋은 결과를 제공하기 위해 큐레이팅된 실습 데이터 세트로 인해 최소한이었지만, 실제 데이터로 작업할 때 시도해 보면 얼마나 잘 작동하는지 놀랄 것입니다!

좋은 웹페이지 즐겨찾기