수식이 나오지 않는다면 새로고침(F5)을 해주세요
모바일은 수식이 나오지 않습니다.
📌 정규화 방법?
우리는 일반적으로 최소자승법을 이용한 회귀를 사용합니다. 하지만 최근 표본의 크기가 커지고, 많은 수의 feature들을 이용하는 빅데이터 시대에서는 한계점이 두드러진 방법입니다.
정규화는 회귀 계수에 제약을 가함으로써 과적합을 방지하고 일반화 성능을 높이는 기법입니다. 깊이 들어가면 편향을 조금 허용하는 대신, 분산을 줄이는 것이라고 볼 수 있습니다.
그렇다면 회귀 계수에 제약을 가한다는 것은 무엇인가?
바로 변수 선택을 통해 오차는 낮추고 차원 축소를 하는 것입니다. 이를 어떻게 진행하는지 알아보려고 합니다.
📌 Ridge regression(릿지 회귀)
릿지
는 하나의 정규화 방법으로 변수들 사이의 공변량을 조정해줍니다. 한번 아래의 설명과 함께 봅시다.
아래와 같은 linear regression(선형 회귀)가 있습니다.
$$
y_i = \beta_0 + \sum_{j=1}^p \beta_j x_{ij} + \epsilon_i
$$
여기서 볼건 $x$가 2차원이라는 것입니다. 1차원 벡터가 아닌 행렬로 나타날 것입니다.
이에 따른 least squres solution
은 아래와 같습니다.
$$
\hat{\beta}_S = (X^TX)^{-1}X^TY
$$
왜 이런 식이 나오는지는 아래 블로그를 참고해주세요. 자세히 나와있어 보기 좋습니다.
자 여기서 $\hat{\beta_S}$의 공변량은 아래와 같습니다.
$$
Cov(\hat{\beta_S}) = \sigma^2(X^TX)^{-1}
$$
문제는
만약 predictor들이 선형 종속이라면 $X^TX$가 특이행렬로, 평균 제곱 오차가 커질 수 있습니다. 우리는 이러한 문제를 다중공선성
이라고 합니다.
특이행렬은 행렬의 rank가 행렬의 차원보다 작아 역행렬을 계산할 수 없습니다.
◼️ Ridge 접근
이를 위해 ridge estimator
를 이용합니다.
$$
\hat{\beta_\lambda} = (X^TX + \lambda I)^{-1}X^TY
$$
보시면 원래 least squres solution
에 $\lambda I$가 추가됐습니다. 이 estimator는 패널티가 부여된 제곱 오차의 합을 최소화합니다. 아래 식을 한번 봅시다.
$$
\sum_{i=1}^n(y_i - \beta_0 - \sum_{j=1}^p \beta_j x_{ij})^2 + \lambda\sum_{j=1}^p \beta_j^2
$$
- $\lambda$ : shrinkage parameter. 우리가 정해줄 수 있는 파라미터 입니다.
- 만약 $\lambda=0$으로 간다면??
ridge estimator = least squreas estimator
가 됩니다. 패널티 항인 $\lambda\sum_{j=1}^p \beta_j^2 =0$이 되니까요. - 만약 $\lambda \rightarrow \infty$로 간다면?? 전체식을 최소화하기 위해서는 $\beta_j^2$값이 0에 가까워야 합니다.($\hat{\beta}_{Ridge} \rightarrow 0$). 즉 회귀했을 시, 변수들의 estimator가 0에 가까운 것이죠.
결국?
목적은 이 $\lambda$항을 우리가 조절하여 estimator들을 조정함으로서 다중공선성의 영향을 감소시킬 수 있습니다.
정말 쉽게 설명한다면, 우리가 회귀 분석을 하고 나오는 coef값들에 대해 영향력이 적은 coef를 더욱 작은 값으로 정규화할 수 있다는 것 입니다.
릿지 회귀를 적용하기 전에 predictor들을 표준화해야하며, reponse또한 중심화되어야 합니다.(평균 0으로)
◼️ With R
- Boston data이용해 medv 예측
# Boston data의 medv예측 위해 x, y나누기
library(MASS)
x = model.matrix(medv~., Boston)[,-1]
y = Boston$medv
- glmnet 라이브러리 이용해서 릿지 회귀
# glmnet 통해서 릿지 회귀
library(glmnet)
grid = 10^seq(10,-2, length=100) # 람다 만들어주기
ridge = glmnet(x,y,alpha=0, lambda=grid) # alpha=0일 때 릿지
# 람다값 확인
str(grid)
>> num [1:100] 1.00e+10 7.56e+09 5.72e+09 4.33e+09 3.27e+09
str(grid) 값을 보면 100개의 lambda가 있고, 상위 5개의 값을 봅니다.
- 결과 확인
# 결과를 보면 각 feature(beta0~beta13), 각각의 람다 갯수 100개
dim(coef(ridge))
>> 14 100
# 람다 별 coef값
print(coef(ridge))
이러한 값들이 100개가 나오는 것입니다.
# 한번 42번째 람다일 때 값을 보자.
predict(ridge, s=42, type='coefficient')
42번째 람다값일 때 각 변수의 coef값입니다.
10-fold로 해보기
# 데이터 스플릿 8:2
library(caTools)
x = model.matrix(medv ~ ., data = Boston)[,-1] # intercept를 제외한 행렬
y = Boston$medv
set.seed(42)
split = sample.split(y, SplitRatio = 0.8)
train = which(split==TRUE)
test = which(split==FALSE)
x_train = x[train,]
x_test = x[test,]
y_train = y[train]
y_test = y[test]
# 10-fold cv(default가 10fold)
cv = cv.glmnet(x_train, y_train, alpha=0)
plot(cv)
그래프 보시면 0과2사이에서 2에 가까울때가 best인 것 같은데 best lambda 값을 한번 봅시다.
# best lambda보기
best = cv$lambda.min
best
>> 0.7010396
best 람다를 보았으니 마지막으로 전체 데이터에 적용해봅시다.
# best lambda로 cv가 아닌 전체 데이터에 해보자
final = glmnet(x_train, y_train, alpha=0, lambda=best)
# pred 하, mean square error 구하기
pred = predict(final, x_test)
mean((y_test-pred)^2)
>> 25.66486
📌 Lasso regression(라쏘 회귀)
LASSO
가 Least Absolute Shrinkage and Selection Operator
입니다. 중간에 Selection이 있죠?? 릿지와는 다르게 계수($\beta$)가 0이 될 수 있습니다. 즉, 릿지와는 다른 방법으로 계수를 0으로 만들어 정말 다중공선성에 걸리지 않고 원하는 intercept만 얻을 수 있는 것 입니다.
◼️ Lasso 접근
Ridge와 다른 LASSO solution
을 보겠습니다. 아래를 최소화 해주는 것입니다.
$$
\sum_{i=1}^n(y_i - \beta_0 - \sum_{j=1}^p \beta_j x_{ij})^2 + \lambda \sum_{j=1}^p |\beta_j |
$$
Lidge식과는 다르게 마지막 페널티 항에서 제곱이 아닌 절댓값을 구해줍니다.
- 만약 $\lambda=0$으로 간다면??
lasso estimator = least squreas estimator
가 됩니다. 이건 릿지와 같은이유죠. - 만약 $\lambda \rightarrow \infty$로 간다면?? 전체식을 최소화하기 위해서는 $|\beta_j|$값이 0이 될 수 있습니다.
왜
Lasso는 계수가 0이 되는데 Lidge는 되지 않는지는 아래 블로그에 잘 정리되어 있는 것 같습니다.
◼️ With R
- Boston data이용해 medv 예측
# Boston data의 medv예측 위해 x, y나누기
library(MASS)
x = model.matrix(medv~., Boston)[,-1]
y = Boston$medv
- glmnet 라이브러리 이용해서 릿지 회귀
library(glmnet)
grid = 10^seq(10,-2,length=100) # 보통 lambda를 이렇게 넣어준다고
lasso.mod = glmnet(x,y,alpha=1,lambda=grid) # alpha 1일때 라쏘
# 람다값 확인
str(grid)
>> num [1:100] 1.00e+10 7.56e+09 5.72e+09 4.33e+09 3.27e+09
str(grid) 값을 보면 100개의 lambda가 있고, 상위 5개의 값을 봅니다.
- 결과 확인
# 결과를 보면 각 feature(beta0~beta13), 각각의 람다 갯수 100개
dim(coef(lasso))
>> 14 100
# 람다 별 coef값
print(coef(lasso))
coef 차이
위 lasso coef를 보시면 intercept를 제외한 값들이 모두 0입니다. 이게 ridge와 lasso의 차이입니다. 람다값이 매우 클수록 각 베타의 계수들이 거의 0이 됩니다.
10-fold로 해보기
# 데이터 스플릿 8:2
library(caTools)
x = model.matrix(medv ~ ., data = Boston)[,-1] # intercept를 제외한 행렬
y = Boston$medv
set.seed(42)
split = sample.split(y, SplitRatio = 0.8)
train = which(split==TRUE)
test = which(split==FALSE)
x_train = x[train,]
x_test = x[test,]
y_train = y[train]
y_test = y[test]
# 10-fold cv(default가 10fold)
cv = cv.glmnet(x_train, y_train, alpha=1)
plot(cv)
똑같이 best lambda를 구하고 predict 해봅시다.
# best lambda보기
best = cv$lambda.min
best
# 전체 데이터가지고 fit
final = glmnet(x_train,y_train, alpha=1, lambda=best)
# pred
pred=predict(final, x_test)
mean((y_test-pred)^2)
>> 24.54536
릿지를 했을 때 보다 조금 더 작게 나왔습니다.
lambda 값에 따른 coef 0의 개수 변화
# traced 그림. log lambda값에 따라서 몇개가 0이 아닌지 그래프 위 숫자에서 보여줌.
plot(lasso, xvar='lambda', label=TRUE)
그림을 보시면 그래프 위 축은 coef = 0이 아닌 것의 개수입니다. log lambda값이 커질 수록 대부분의 coef값이 0이 되는 것을 볼수 있습니다.
'🌞 Statistics for AI > Regularization' 카테고리의 다른 글
정규화 방법 : 엘라스틱 넷(Elastic Nets) (0) | 2024.02.16 |
---|