R
插入符號 glmnet 與 cv.glmnet
glmnet
在比較使用withincaret
搜索最佳 lambda 和 usingcv.glmnet
執行相同任務時,似乎存在很多混淆。提出了許多問題,例如:
分類模型 train.glmnet 與 cv.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)
總而言之,最佳 lambda 表達式如下:
- 0.055 通過使用
cv.glmnet()
- 0.001 通過使用
train()
我知道使用
standardize=FALSE
incv.glmnet()
是不可取的,但我真的想使用相同的先決條件比較這兩種方法。作為主要解釋,我認為每個折疊的抽樣方法可能是一個問題——但我使用相同的種子,結果卻大不相同。所以我真的很困惑為什麼這兩種方法如此不同,而它們應該非常相似?- 我希望社區對這裡的問題有所了解
我在這裡看到兩個問題。首先,你的訓練集相對於你的測試集來說太小了。通常,我們需要一個至少在大小上與測試集相當的訓練集。另一個注意事項是,對於交叉驗證,您根本沒有使用測試集,因為該算法基本上使用“訓練集”為您創建測試集。所以你最好使用更多的數據作為你的初始訓練集。
其次,3 折太小,你的簡歷不可靠。通常,建議 5-10 折(
nfolds = 5
forcv.glmnet
和number=5
forcaret
)。通過這些更改,我在兩種方法中得到了相同的 lambda 值和幾乎相同的估計值: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