glmnet交叉验证中默认的lambda序列

13

请问有人知道 cv.glmnet (在 R 的 glmnet 中) 或 LassoCV (scikit-learn 中的) 如何选择一系列正则化常数 (lambda),并在交叉验证中使用它们吗?非常感谢!


(在 R 的 glmnet 中)永远不要使用默认的 lambda 序列,这被认为是危险的。始终提供自己的序列。 - smci
@smci,您能解释一下glmnet中默认lambda序列为什么/以何种方式是危险的吗?谢谢。 - visitor
@visitor:“不一定保证找到最小化CVE的lambda。”可能会找到,也可能不会。绘制偏差/对数(lambda)曲线以查看是否找到它。我一直得到的建议是定义自己的lambda序列,并在需要时进行调整。 - smci
1个回答

14
根据Friedman、Hastie和Tibshirani(2010)的说法,"策略是选择最小值lambda_min = epsilon * lambda_max,并构建一个在对数刻度下从lambda_max到lambda_min递减的K个lambda值序列。典型值为epsilon = 0.001和K = 100。"
以下示例生成数据,计算lambda路径并将其与glmnet进行比较。
## Load library and generate some data to illustrate:
library("glmnet")
set.seed(1)
n <- 100
x <- matrix(rnorm(n*20), n, 20)
y <- rnorm(n)

## Standardize variables: (need to use n instead of (n-1) as denominator)
mysd <- function(z) sqrt(sum((z-mean(z))^2)/length(z))
sx <- scale(x, scale = apply(x, 2, mysd))
sx <- as.matrix(sx, ncol = 20, nrow = 100)

## Calculate lambda path (first get lambda_max):
lambda_max <- max(abs(colSums(sx*y)))/n
epsilon <- .0001
K <- 100
lambdapath <- round(exp(seq(log(lambda_max), log(lambda_max*epsilon), 
                            length.out = K)), digits = 10)
lambdapath

## Compare with glmnet's lambda path:
fitGLM <- glmnet(sx, y)
fitGLM$lambda

请注意,glmnet并不计算所有100(默认)个lambda值的解,它会提前停止。不确定停止规则是什么。
另请参见:glmnet如何计算最大lambda值

Friedman, J., Hastie, T., & Tibshirani, R. (2010).通过坐标下降法进行广义线性模型的正则化路径。《统计软件学报》,33(1),1。


1
看起来你对 y 向量进行了归一化,然后计算了 lambda_max。根据包的说明,y 只被居中而不是缩放??? - mert
确实如此。但是,如果您将行sy <- as.vector(scale(y, scale = mysd(y)))替换为sy <- y,则计算出的lambdapathfitGLM$lambda仍然相等。 - Marjolein Fokkema
现在省略了对 y 的归一化处理。 - Marjolein Fokkema

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