R

插入符號 glmnet 與 cv.glmnet

  • August 24, 2017

glmnet在比較使用withincaret搜索最佳 lambda 和 usingcv.glmnet執行相同任務時,似乎存在很多混淆。

提出了許多問題,例如:

分類模型 train.glmnet 與 cv.glmnet?

將 glmnet 與插入符號一起使用的正確方法是什麼?

使用 caret 交叉驗證 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=FALSEincv.glmnet()是不可取的,但我真的想使用相同的先決條件比較這兩種方法。作為主要解釋,我認為每個折疊的抽樣方法可能是一個問題——但我使用相同的種子,結果卻大不相同。

所以我真的很困惑為什麼這兩種方法如此不同,而它們應該非常相似?- 我希望社區對這裡的問題有所了解

我在這裡看到兩個問題。首先,你的訓練集相對於你的測試集來說太小了。通常,我們需要一個至少在大小上與測試集相當的訓練集。另一個注意事項是,對於交叉驗證,您根本沒有使用測試集,因為該算法基本上使用“訓練集”為您創建測試集。所以你最好使用更多的數據作為你的初始訓練集。

其次,3 折太小,你的簡歷不可靠。通常,建議 5-10 折(nfolds = 5forcv.glmnetnumber=5for caret)。通過這些更改,我在兩種方法中得到了相同的 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

引用自:https://stats.stackexchange.com/questions/299653

comments powered by Disqus