glmnet如何计算最大的lambda值?

9
glmnet包使用一系列LASSO调整参数lambda,这些参数是从最大的lambda_max开始缩放的,该值下没有选择任何预测变量。我想知道glmnet如何计算lambda_max值。例如,在一个简单的数据集中:
set.seed(1)
library("glmnet")
x <- matrix(rnorm(100*20),100,20)
y <- rnorm(100)
fitGLM <- glmnet(x,y)
max(fitGLM$lambda)
# 0.1975946

包说明文档(http://www.jstatsoft.org/v33/i01/paper) 第2.5节描述了它计算此值的方法如下:

sx <- as.matrix(scale(x))
sy <- as.vector(scale(y))
max(abs(colSums(sx*sy)))/100
# 0.1865232

这明显是接近但不完全相同的值。那么,是什么原因导致了这种差异呢?在一个相关的问题中,我如何计算逻辑回归的lambda_max

5个回答

9
为了得到相同的结果,您需要使用标准偏差来标准化变量,分母为n而不是n-1
mysd <- function(y) sqrt(sum((y-mean(y))^2)/length(y))
sx <- scale(x,scale=apply(x, 2, mysd))
sx <- as.matrix(sx, ncol=20, nrow=100)
sy <- as.vector(scale(y, scale=mysd(y)))
max(abs(colSums(sx*sy)))/100
## [1] 0.1758808
fitGLM <- glmnet(sx,sy)
max(fitGLM$lambda)
## [1] 0.1758808

对于未经缩放(原始)xy,最大的λ应该是:
mysd <- function(y) sqrt(sum((y-mean(y))^2)/length(y))
sx <- scale(x,scale=apply(x, 2, mysd))
norm(t(sx) %*% y, 'i') / nrow(x) 
## [1] 0.1975946
# norm of infinity is also equal to 
max(abs(colSums(sx*y)))/100
## [1] 0.1975946
max(fitGLM$lambda) - norm(t(sx) %*% y, 'i') / nrow(x)
## [1] 2.775558e-17

这个问题的第二部分在这里回答了吗? - ved
1
这似乎只回答了在x和y预先缩放的情况下计算lambda路径的问题。如果x和y是原始数据,那么如何计算lambda路径? - Johan Larsson

5

似乎逻辑回归中的lambda_max计算方式与线性回归类似,但权重基于类别比例:

set.seed(1)
library("glmnet")
x <- matrix(rnorm(100*20),100,20)
y <- rnorm(100)

mysd <- function(y) sqrt(sum((y-mean(y))^2)/length(y))
sx <- scale(x, scale=apply(x, 2, mysd))
sx <- as.matrix(sx, ncol=20, nrow=100)

y_bin <- factor(ifelse(y<0, -1, 1))
prop.table(table(y_bin)) 
# y_bin
#   -1    1 
# 0.62 0.38 
fitGLM_log <- glmnet(sx, y_bin, family = "binomial")
max(fitGLM_log$lambda)
# [1] 0.1214006
max(abs(colSums(sx*ifelse(y<0, -.38, .62))))/100
# [1] 0.1214006

3

1

抱歉,有些时间没联系了,但可能还是有帮助的:

使用L1正则化计算问题的最大λ值可以通过找到完全正则化模型(例如,所有受惩罚的参数设为零)的优化参数值处目标函数(即可能性得分的评分函数)梯度的最高绝对值来实现。

不过,我无法解释数值上的差异。虽然我可以说我尝试使用稍高一些的最大λ值 - 比如比计算出的最大λ值高5%左右,这样所有选定参数受限制的模型都肯定是估计模型中的一部分。也许这就是glmnet中正在做的事情。

编辑:抱歉,我混淆了非正则化和完全惩罚模型。现在已进行了编辑。


0
根据 help("glmnet"),最大的 lambda 值是“所有系数均为零的最小值”:
sum(fitGLM$beta[, which.max(fitGLM$lambda)])
#[1] 0
sum(glmnet(x,y, lambda=max(fitGLM$lambda)*0.999)$beta)
#[1] -0.0001809804

快速浏览一下,该值似乎是由elnet调用的Fortran代码计算出来的。


谢谢,我知道最大的λ是系数为零的最小值。我也试过在GitHub上浏览Fortran代码,不幸的是Fortran对我来说太陌生了,我完全无法理解它... - Sacha Epskamp

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接