[Regularization] 1SE Rule
1SE Rule
`1 Standard Error Rule (1SE Rule)`은 전통적인 통계 모형 선택 과정에서, 특히 교차검증(cross-validation)을 통해 여러 하이퍼파라미터나 모델의 복잡도를 비교할 때 사용되는 규칙입니다. 이 규칙은 일반적으로 최적의 성능을 내는 모델 대신, 더 간단한 모델을 선택하여 과적합(overfitting)을 방지하고, 모델의 일반화 성능을 높이기 위한 목적에서 사용됩니다.
교차검증을 통해 여러 하이퍼파라미터(예: Constraint parameter, Tree depth, Dropout rate 등)에 대해 모델의 성능을 평가한다고 가정해봅시다. 이때 각 하이퍼파라미터 값에 대해 여러 번의 교차검증이 수행되므로, 각 하이퍼파라미터에 대한 평균 성능(MSE의 평균 or F1-score 평균과 같은)을 구할 수 있습니다. `1se Rule`은 이를 통해 구한 파라미터의 1 표준편차 내에서 가장 간단한 모델을 선택하는 방법입니다. 일반적으로 통계 모델에서는 최적의 파라미터에서 차선의 파라미터로 약간만 값을 조정하면 훨씬 더 간단한 모델을 사용할 수 있기때문에 나온 아이디어라 생각됩니다.
1SE Rule의 구체적인 과정은 다음과 같습니다:
1. 각 하이퍼파라미터 값 $\lambda_i$에 대해 평균 성능을 구합니다
$$ \text{Mean Performance}_i = \frac{1}{K} \sum_{k=1}^{K} \text{Performance}_{i,k} $$
여기서 $K$는 교차검증의 폴드 수, $Performance_{i,k}$는 $λ_i$에 대한 $k$번째 폴드의 성능입니다.
2. 각 하이퍼파라미터 값에 대한 성능의 표준 오차(Standard Error, SE)를 계산합니다.
$$\text{SE}_i = \frac{\sigma_i}{\sqrt{K}}$$
여기서 $σ_i$는 $λ_i$에 대한 교차검증 성능의 표준 편차(Standard Deviation)입니다.
3. 최적의 평균 성능을 갖는 하이퍼파라미터를 찾습니다. (MSE의 경우 최솟값이, F1-score의 경우 최댓값이 되겠죠?)
$$\text{Best Performance} = Best(\text{Mean Performance}_i)$$
4. 1SE Rule에 따라, 최적의 성능을 가지는 하이퍼파라미터 $λ^*$에서 1 표준 오차 범위 내에 있는 가장 단순한 모델을 선택합니다.
$$\text{Select } \lambda_j \text{ such that } | \text{Best Performance} - \text{Mean Performance}_j |\leq \text{SE}_{\lambda^*}$$
이를 만족하는 $\lambda_j$가 `1se`방식으로 선택된 하이퍼파라미터 입니다.
이 과정에서 가장 단순한 모델은 일반적으로 변수의 수가 적은 모델을 의미합니다. LASSO의 경우 하이퍼파라미터$\lambda$ 값이 클 때 constraint가 강해져 모델이 단순해지기 때문에 $\lambda$값이 큰 경우를 선택하게 됩니다.
예시
LASSO regression 모델에 교차검증을 통해 대한 최적화를 함에 있어, `minimum mse`와 `1se`의 결과를 비교해보겠습니다.
library(glmnet)
library(tidyverse)
# 시뮬레이션 데이터 생성
set.seed(42)
n <- 200 # 샘플 수
p <- 100 # 피처 수
X <- matrix(rnorm(n * p), nrow = n, ncol = p) # 무작위로 생성된 독립 변수
beta <- c(rep(5, 10), rep(0, p - 10)) # 10개의 유의미한 변수와 90개의 노이즈
y <- X %*% beta + rnorm(n, sd = 10) # 종속 변수 생성, 노이즈 추가
# 훈련 세트와 테스트 세트로 분할
train_indices <- sample(1:n, size = round(0.7 * n))
X_train <- X[train_indices, ]
y_train <- y[train_indices]
X_test <- X[-train_indices, ]
y_test <- y[-train_indices]
# LassoCV 모델 훈련
lasso_cv <- cv.glmnet(X_train, y_train, alpha = 1)
# 단순 MSE 최저값 기준 최적의 lambda
best_lambda_min_mse <- lasso_cv$lambda.min
# 1se rule 기준 최적의 lambda
best_lambda_1se <- lasso_cv$lambda.1se
# 각 lambda에 대한 성능 평가
pred_min_mse <- predict(lasso_cv, s = best_lambda_min_mse, newx = X_test)
pred_1se <- predict(lasso_cv, s = best_lambda_1se, newx = X_test)
mse_min_mse <- mean((y_test - pred_min_mse)^2)
mse_1se <- mean((y_test - pred_1se)^2)
# 결과 출력
cat("최소 MSE 기준 최적의 lambda: ", best_lambda_min_mse, "\n")
cat("1se rule 기준 최적의 lambda: ", best_lambda_1se, "\n")
cat("테스트 세트에서 최소 MSE 기준의 MSE: ", mse_min_mse, "\n")
cat("테스트 세트에서 1se rule 기준의 MSE: ", mse_1se, "\n")
최소 MSE 기준 최적의 lambda: 0.9455433
1se rule 기준 최적의 lambda: 1.652364
테스트 세트에서 최소 MSE 기준의 MSE: 188.9603
테스트 세트에서 1se rule 기준의 MSE: 186.0504
LASSO의 $\lambda$도 어느정도 차이나며, 테스트에서의 `mse`는 `min`보다 `1se` 방법이 조금 더 좋은걸 확인할 수 있습니다.
> print(lasso_cv)
Call: cv.glmnet(x = X_train, y = y_train, alpha = 1)
Measure: Mean-Squared Error
Lambda Index Measure SE Nonzero
min 0.9455 25 150.8 14.78 30
1se 1.6524 19 163.6 16.53 18
위는 LASSO 교차검증의 결과입니다. $\lambda = 0.9455$ 일 때 `min mse`를 갖고 그 값은 $mse=150.8$이며, $\lambda = 1.6524$ 일 때 `1se mse`를 갖으며 그 값은 $mse=163.6$입니다. `SE`는 각 $\lambda$에서 계산된 mse의 표준오차를 나타내며, `Nonzero`는 선택된 변수를 의미합니다. `min mse`를 선택하는 경우 총 30개의 변수를 선택하는것을 의미하며, `1se mse`의 경우에는 18개의 변수를 선택하게 됩니다.
> plot(lasso_cv)
여기서 두 수직 점선은 왼쪽부터 `min mse`와 `1se mse`의 경우를 의미합니다. LASSO이며 regression이다보니, 가장 작은 mse를 선택하고, 그 `1se`내에서 $\lambda$의 값이 가장 커 ($Log(\lambda)$이 가장 작아) 단순한 모델을 선택하게 됩니다.
DNN에 적용?
실제 데이터를 통해 과적합을 해결하는 예시를 보이고 싶었습니다. 하지만, LASSO로는 R에 있는 데이터 셋중 car, Boston, Wage, Hitters 등등 사용해보았는데, test에서의 성능은 심한 과소적합 또는 그냥 `min mse`가 가장 좋았습니다. `1se` 방법은 과적합이 자주 발생하는 DNN같은 모델에 사용해야하나 싶습니다.
이런 생각으로 DNN과 1se 방법을 찾아보았지만 잘 나오지 않는걸 보니, `1se Rule`은 통계적 학습 이론에서 주로 사용되는 개념 같습니다. 그래도 DNN에 사용되는 시나리오를 생각해보면 통계에서와 마찬가지로 과적합 방지, 일반화 성능 향상, 보다 간단한 모델의 선택이 가능해보입니다.
하지만, DNN은 비선형적인 패턴을 인식하고, 그를 위해 많은 피쳐의 수와 그에 따른 많은 샘플의 수가 일반적인 세팅입니다. 따라서 폴드 각각 시나리오마다의 성능은 유사할 것으로 생각되며, 표준 오차값이 굉장히 적을 것으로 생각됩니다. 따라서 `1se`를 사용해도 미미한 일반화 성능의 향상이 있을 듯 합니다.
혹시 DNN에 적용해보셨거나 좋은 아이디어 및 의견이 있으면 댓글로 알려주세요!