首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >r:对于同一个lambda,glmnet和脱字符的系数是不同的

r:对于同一个lambda,glmnet和脱字符的系数是不同的
EN

Stack Overflow用户
提问于 2018-02-07 07:11:47
回答 1查看 1.9K关注 0票数 0

我已经读了一些关于这方面的问答,但我仍然不确定我是否理解,为什么基于相同样本和相同超参数的glmnet和脱字符模型的系数略有不同。会非常感谢你的解释!

我正在使用插入符号训练一个岭回归:

代码语言:javascript
运行
复制
library(ISLR)
Hitters = na.omit(Hitters)
x = model.matrix(Salary ~ ., Hitters)[, -1] #Dropping the intercept column.
y = Hitters$Salary

set.seed(0)
train = sample(1:nrow(x), 7*nrow(x)/10)

library(caret)
set.seed(0)
train_control = trainControl(method = 'cv', number = 10)
grid = 10 ^ seq(5, -2, length = 100)
tune.grid = expand.grid(lambda = grid, alpha = 0)
ridge.caret = train(x[train, ], y[train],
                    method = 'glmnet',
                    trControl = train_control,
                    tuneGrid = tune.grid)
ridge.caret$bestTune
# alpha is 0 and best lambda is 242.0128

现在,我使用上面找到的lambda (和alpha)来训练整个数据集的岭回归。最后,我提取系数:

代码语言:javascript
运行
复制
ridge_full <- train(x, y,
                    method = 'glmnet',
                    trControl = trainControl(method = 'none'), 
                    tuneGrid = expand.grid(
                      lambda = ridge.caret$bestTune$lambda, alpha = 0)
                    )
coef(ridge_full$finalModel, s = ridge.caret$bestTune$lambda)

最后,使用完全相同的alpha和lambda,我尝试使用glmnet包拟合相同的岭回归-并提取系数:

代码语言:javascript
运行
复制
library(glmnet)
ridge_full2 = glmnet(x, y, alpha = 0, lambda = ridge.caret$bestTune$lambda)
coef(ridge_full2)
EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2018-02-07 14:26:20

原因是您指定的lambda没有被插入符号使用。您可以通过以下方式进行检查:

代码语言:javascript
运行
复制
ridge_full$finalModel$lambda

最接近的值为261.28915和238.07694。

当你这样做的时候

代码语言:javascript
运行
复制
coef(ridge_full$finalModel, s = ridge.caret$bestTune$lambda)

其中s是242.0128,根据实际计算的系数对系数进行插值。

因此,当您将lambda提供给glmnet调用时,模型将返回该lambda的确切系数,这与插入的插入符号返回的系数仅略有不同。

发生这种情况的原因:

当您指定一个alpha和一个lambda对所有数据进行拟合时,插入符号将实际拟合:

代码语言:javascript
运行
复制
   fit = function(x, y, wts, param, lev, last, classProbs, ...) {
                    numLev <- if(is.character(y) | is.factor(y)) length(levels(y)) else NA

                    theDots <- list(...)

                    if(all(names(theDots) != "family")) {
                      if(!is.na(numLev)) {
                        fam <- ifelse(numLev > 2, "multinomial", "binomial")
                      } else fam <- "gaussian"
                      theDots$family <- fam
                    }

                    ## pass in any model weights
                    if(!is.null(wts)) theDots$weights <- wts

                    if(!(class(x)[1] %in% c("matrix", "sparseMatrix")))
                      x <- Matrix::as.matrix(x)

                    modelArgs <- c(list(x = x,
                                        y = y,
                                        alpha = param$alpha),
                                   theDots)

                    out <- do.call(glmnet::glmnet, modelArgs)
                    if(!is.na(param$lambda[1])) out$lambdaOpt <- param$lambda[1]
                    out
                  }

这是从here上拍的。

在您的示例中,这转换为

代码语言:javascript
运行
复制
fit <- glmnet::glmnet(x, y,
                       alpha = 0)

lambda <- unique(fit$lambda)

这些lambda值对应于ridge_full$finalModel$lambda

代码语言:javascript
运行
复制
all.equal(lambda, ridge_full$finalModel$lambda)
#output
TRUE
票数 2
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/48653465

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档