Caret glmnet vs cv.glmnet


14

Optimal bir lambda aramak için glmnetiçeride caretkullanma cv.glmnetve aynı görevi yapmak için kullanma karşılaştırmasında çok fazla karışıklık var gibi görünüyor .

Birçok soru yöneltildi, örneğin:

Sınıflandırma modeli train.glmnet mi cv.glmnet mi?

Glmnet'i caret ile kullanmanın doğru yolu nedir?

"Caret" kullanarak çapraz onaylama "glmnet"

ancak sorunun tekrarlanabilirliğinden kaynaklanabilecek hiçbir cevap verilmemiştir. İlk soruyu takiben oldukça benzer bir örnek veriyorum ama aynı sorum var: Tahmini lambdalar neden bu kadar farklı?

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)

Özetlemek gerekirse, optimal lambdalar şu şekilde verilir:

  • 0.055 kullanarak cv.glmnet()

  • 0.001 kullanarak train()

Ben kullanarak biliyoruz standardize=FALSEiçinde cv.glmnet()tavsiye edilmez, ama gerçekten aynı önkoşul kullanarak her iki yöntemi karşılaştırmak istiyorum. Ana açıklama olarak, her kat için örnekleme yaklaşımının bir sorun olabileceğini düşünüyorum - ama aynı tohumları kullanıyorum ve sonuçlar oldukça farklı.

Bu yüzden, iki yaklaşımın neden bu kadar farklı olduğu konusunda oldukça takılıp kaldım. - Umarım topluluğun burada sorun ne olduğu hakkında bir fikri vardır

Yanıtlar:


17

Burada iki sorun görüyorum. İlk olarak, egzersiz setiniz test setinize göre çok küçük. Normalde, en az test setiyle karşılaştırılabilir bir eğitim seti isteriz. Başka bir not, Çapraz Doğrulama için test setini hiç kullanmamanızdır, çünkü algoritma temel olarak "eğitim seti" ni kullanarak sizin için test setleri oluşturur. Böylece ilk egzersiz setiniz olarak daha fazla veriyi kullanmak daha iyi olur.

İkincisi, 3 kat CV'nizin güvenilir olması için çok küçük. Tipik haliyle, 5-10 kat (önerilir nfolds = 5için cv.glmnetve number=5için caret). Bu değişikliklerle, iki yöntemde ve neredeyse aynı tahminlerde aynı lambda değerlerini aldım:

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)

Sonuç:

> 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

Cevabınız için çok teşekkürler - benim için mükemmel bir mantıklı. CV'ye yeni başlayan biri olduğum için a) numunenin büyüklüğü ve b) kıvrımları hesaba katmadım.
Jogi

Gönderi için teşekkürler! Bu nedenle, doğru yaparsam, genellikle veri kümesini büyük bir eğitim setine ve daha küçük bir test setine (= tutma) böler ve eğitim setinde k katlamalı CV'yi gerçekleştirin. Son olarak, CV setinin sonuçlarını kullanarak test setini doğrular mı?
Jogi

@Jogi Bunu yapmanın yolu bu olurdu. CV, daha fazla validasyona ihtiyacınız yoksa sadece CV için tüm veri kümesini kullanabilirsiniz, çünkü CV zaten test setlerinin her bir yinelemesinde modelin ortalama performansına göre en iyi parametreleri seçer.
StAtS
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.