Caret glmnet กับ cv.glmnet


14

ดูเหมือนจะมีความสับสนมากในการเปรียบเทียบการใช้glmnetภายในcaretเพื่อค้นหาแลมบ์ดาที่ดีที่สุดและใช้cv.glmnetในการทำงานเดียวกัน

มีการตั้งคำถามมากมายเช่น:

โมเดลการจำแนกประเภท train.glmnet vs. cv.glmnet

วิธีที่เหมาะสมในการใช้ glmnet กับคาเร็ตคืออะไร?

การตรวจสอบข้าม `glmnet 'โดยใช้` คาเร็ต'

แต่ไม่ได้รับคำตอบซึ่งอาจเป็นเพราะความสามารถในการทำซ้ำของคำถาม ตามคำถามแรกฉันให้ตัวอย่างที่คล้ายกัน แต่มีคำถามเดียวกัน: ทำไม lambdas โดยประมาณแตกต่างกันอย่างไร

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=FALSEในcv.glmnet()นั้นไม่แนะนำให้เลือก แต่ฉันต้องการเปรียบเทียบทั้งสองวิธีโดยใช้ข้อกำหนดเบื้องต้นเดียวกัน ในฐานะที่เป็นคำอธิบายหลักฉันคิดว่าวิธีการสุ่มตัวอย่างสำหรับแต่ละครั้งอาจเป็นปัญหา - แต่ฉันใช้เมล็ดเดียวกันและผลลัพธ์นั้นแตกต่างกันมาก

ดังนั้นฉันจึงติดอยู่จริงๆว่าทำไมทั้งสองวิธีจึงแตกต่างกันในขณะที่พวกเขาควรจะคล้ายกันมาก? - ฉันหวังว่าชุมชนมีความคิดว่าปัญหาคืออะไรที่นี่

คำตอบ:


17

ฉันเห็นสองประเด็นที่นี่ ก่อนอื่นชุดฝึกอบรมของคุณเล็กเกินไปเมื่อเทียบกับชุดทดสอบของคุณ โดยปกติเราต้องการชุดฝึกอบรมที่มีขนาดเท่ากับชุดทดสอบอย่างน้อยที่สุด หมายเหตุอีกข้อหนึ่งก็คือสำหรับการตรวจสอบความถูกต้องไขว้คุณไม่ได้ใช้ชุดทดสอบเลยเนื่องจากอัลกอริทึมสร้างชุดการทดสอบโดยทั่วไปสำหรับคุณโดยใช้ "ชุดฝึกอบรม" ดังนั้นคุณควรใช้ข้อมูลเป็นชุดฝึกอบรมครั้งแรกของคุณดีกว่า

ประการที่สอง 3 เท่ามีขนาดเล็กเกินไปสำหรับประวัติย่อของคุณที่จะเชื่อถือได้ โดยทั่วไปแล้วจะแนะนำ 5-10 เท่า ( nfolds = 5สำหรับcv.glmnetและnumber=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 ฉันไม่ได้คำนึงถึงก) ขนาดของตัวอย่างและ b) เท่า
Jogi

ขอบคุณสำหรับการโพสต์! ดังนั้นถ้าฉันเข้าใจถูกต้องโดยปกติหนึ่งชุดข้อมูลจะแยกออกเป็นชุดฝึกอบรมขนาดใหญ่และชุดทดสอบขนาดเล็ก (= โฮลเดต) และดำเนินการ k-fold CV ในชุดฝึกอบรม ในที่สุดหนึ่งการตรวจสอบในชุดทดสอบโดยใช้ผลลัพธ์ของ CV ใช่มั้ย
Jogi

@Jogi นั่นเป็นวิธีที่จะทำ คุณสามารถใช้ชุดข้อมูลทั้งหมดสำหรับ CV หากคุณไม่ต้องการการตรวจสอบเพิ่มเติมเนื่องจาก CV เลือกพารามิเตอร์ที่ดีที่สุดตามประสิทธิภาพเฉลี่ยของโมเดลในชุดการทดสอบซ้ำแต่ละชุด
StAtS
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.