캐럿 glmnet vs cv.glmnet


14

glmnetwithin caret을 사용하여 최적의 람다를 검색 cv.glmnet하고 동일한 작업을 수행하는 것을 비교하는 데 많은 혼란이있는 것 같습니다 .

다음과 같은 많은 질문이 제기되었습니다.

분류 모델 train.glmnet 대 cv.glmnet?

캐럿과 함께 glmnet을 사용하는 올바른 방법은 무엇입니까?

`caret`를 사용한 교차 유효성 검사`glmnet`

그러나 질문의 ​​재현 가능성으로 인한 답변이 없습니다. 첫 번째 질문에 이어 비슷한 예를 들지만 같은 질문이 있습니다. 추정 된 람다는 왜 다른가?

library(caret)
library(glmnet)
set.seed(849)
training <- twoClassSim(50, linearVars = 2)
set.seed(849)
testing <- twoClassSim(500, linearVars = 2)
trainX <- training[, -ncol(training)]
testX <- testing[, -ncol(testing)]
trainY <- training$Class

# Using glmnet to directly perform CV
set.seed(849)
cvob1=cv.glmnet(x=as.matrix(trainX),y=trainY,family="binomial",alpha=1, type.measure="auc", nfolds = 3,lambda = seq(0.001,0.1,by = 0.001),standardize=FALSE)

cbind(cvob1$lambda,cvob1$cvm)

# best parameter
cvob1$lambda.mi

# best coefficient
coef(cvob1, s = "lambda.min")


# Using caret to perform CV
cctrl1 <- trainControl(method="cv", number=3, returnResamp="all",classProbs=TRUE,summaryFunction=twoClassSummary)
set.seed(849)
test_class_cv_model <- train(trainX, trainY, method = "glmnet", trControl = cctrl1,metric = "ROC",
                             tuneGrid = expand.grid(alpha = 1,lambda = seq(0.001,0.1,by = 0.001)))


test_class_cv_model 

# best parameter
test_class_cv_model$bestTune

# best coefficient
coef(test_class_cv_model$finalModel, test_class_cv_model$bestTune$lambda)

요약하면 최적의 람다는 다음과 같이 제공됩니다.

  • 를 사용하여 0.055 cv.glmnet()

  • 사용하여 0.001 train()

standardize=FALSEin 을 사용 하는 cv.glmnet()것이 바람직하지 않다는 것을 알고 있지만 동일한 전제 조건을 사용하여 두 방법을 비교하고 싶습니다. 주요 설명으로, 각 폴드에 대한 샘플링 접근법이 문제가 될 수 있다고 생각합니다. 그러나 동일한 시드를 사용하고 결과는 상당히 다릅니다.

그래서 나는 두 접근법이 왜 그렇게 다른지에 여전히 붙어 있지만 그것들은 상당히 유사해야합니까? -커뮤니티에 문제가 무엇인지 알기를 바랍니다.

답변:


17

여기에 두 가지 문제가 있습니다. 먼저 훈련 세트가 테스트 세트에 비해 너무 작습니다. 일반적으로 테스트 세트와 크기가 비슷한 훈련 세트를 원할 것입니다. 또 다른 참고 사항은 알고리즘이 기본적으로 "트레이닝 세트"를 사용하여 테스트 세트를 생성하기 때문에 교차 검증의 경우 테스트 세트를 전혀 사용하지 않는다는 것입니다. 따라서 초기 교육 세트로 더 많은 데이터를 사용하는 것이 좋습니다.

둘째, CV를 신뢰할 수 없을 정도로 3 배가 너무 작습니다. 일반적으로 5 ~ 10 폴드 (권장 nfolds = 5을 위해 cv.glmnetnumber=5위해 caret). 이러한 변경으로 두 방법과 거의 동일한 추정치에서 동일한 람다 값을 얻었습니다.

set.seed(849)
training <- twoClassSim(500, linearVars = 2)
set.seed(849)
testing <- twoClassSim(50, linearVars = 2)
trainX <- training[, -ncol(training)]
testX <- testing[, -ncol(testing)]
trainY <- training$Class

# Using glmnet to directly perform CV
set.seed(849)
cvob1=cv.glmnet(x=as.matrix(trainX), y=trainY,family="binomial",alpha=1, 
                type.measure="auc", nfolds = 5, lambda = seq(0.001,0.1,by = 0.001),
                standardize=FALSE)

cbind(cvob1$lambda,cvob1$cvm)

# best parameter
cvob1$lambda.min

# best coefficient
coef(cvob1, s = "lambda.min")


# Using caret to perform CV
cctrl1 <- trainControl(method="cv", number=5, returnResamp="all",
                       classProbs=TRUE, summaryFunction=twoClassSummary)
set.seed(849)
test_class_cv_model <- train(trainX, trainY, method = "glmnet", 
                             trControl = cctrl1,metric = "ROC",
                             tuneGrid = expand.grid(alpha = 1,
                                                    lambda = seq(0.001,0.1,by = 0.001)))

test_class_cv_model 

# best parameter
test_class_cv_model$bestTune

# best coefficient
coef(test_class_cv_model$finalModel, test_class_cv_model$bestTune$lambda)

결과:

> cvob1$lambda.min
[1] 0.001

> coef(cvob1, s = "lambda.min")
8 x 1 sparse Matrix of class "dgCMatrix"
1
(Intercept) -0.781015706
TwoFactor1  -1.793387005
TwoFactor2   1.850588656
Linear1      0.009341356
Linear2     -1.213777391
Nonlinear1   1.158009360
Nonlinear2   0.609911748
Nonlinear3   0.246029667

> test_class_cv_model$bestTune
alpha lambda
1     1  0.001

> coef(test_class_cv_model$finalModel, test_class_cv_model$bestTune$lambda)
8 x 1 sparse Matrix of class "dgCMatrix"
1
(Intercept) -0.845792624
TwoFactor1  -1.786976586
TwoFactor2   1.844767690
Linear1      0.008308165
Linear2     -1.212285068
Nonlinear1   1.159933335
Nonlinear2   0.676803555
Nonlinear3   0.309947442

귀하의 답변에 감사드립니다-그것은 나에게 완벽하게 이해됩니다. 나는 CV의 초보자이기 때문에 a) 샘플의 크기와 b) 접기를 설명하지 않았습니다.
Jogi

게시물 주셔서 감사합니다! 내가 올바르게 이해하면 일반적으로 데이터 세트를 큰 훈련 세트와 작은 시험 세트 (= 홀드 아웃)로 나누고 훈련 세트에서 k- 폴드 CV를 수행합니다. 마지막으로 CV의 결과를 사용하여 테스트 세트에서 유효성을 검사합니까?
Jogi

@Jogi 그렇게하는 방법이 될 것입니다. CV는 이미 테스트 세트의 각 반복에서 모델의 평균 성능을 기반으로 최상의 매개 변수를 선택하므로 추가 검증이 필요하지 않은 경우 CV에 전체 데이터 세트를 사용할 수도 있습니다.
StAtS
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.