在“最佳”λ处获取glmnet系数

23

我正在使用glmnet的以下代码:

> library(glmnet)
> fit = glmnet(as.matrix(mtcars[-1]), mtcars[,1])
> plot(fit, xvar='lambda')

enter image description here

但是,我想打印出最佳Lambda处的系数,就像岭回归一样。我看到拟合的结构如下:

> str(fit)
List of 12
 $ a0       : Named num [1:79] 20.1 21.6 23.2 24.7 26 ...
  ..- attr(*, "names")= chr [1:79] "s0" "s1" "s2" "s3" ...
 $ beta     :Formal class 'dgCMatrix' [package "Matrix"] with 6 slots
  .. ..@ i       : int [1:561] 0 4 0 4 0 4 0 4 0 4 ...
  .. ..@ p       : int [1:80] 0 0 2 4 6 8 10 12 14 16 ...
  .. ..@ Dim     : int [1:2] 10 79
  .. ..@ Dimnames:List of 2
  .. .. ..$ : chr [1:10] "cyl" "disp" "hp" "drat" ...
  .. .. ..$ : chr [1:79] "s0" "s1" "s2" "s3" ...
  .. ..@ x       : num [1:561] -0.0119 -0.4578 -0.1448 -0.7006 -0.2659 ...
  .. ..@ factors : list()
 $ df       : int [1:79] 0 2 2 2 2 2 2 2 2 3 ...
 $ dim      : int [1:2] 10 79
 $ lambda   : num [1:79] 5.15 4.69 4.27 3.89 3.55 ...
 $ dev.ratio: num [1:79] 0 0.129 0.248 0.347 0.429 ...
 $ nulldev  : num 1126
 $ npasses  : int 1226
 $ jerr     : int 0
 $ offset   : logi FALSE
 $ call     : language glmnet(x = as.matrix(mtcars[-1]), y = mtcars[, 1])
 $ nobs     : int 32
 - attr(*, "class")= chr [1:2] "elnet" "glmnet"

但是我无法获得最佳的Lambda和相应的系数。感谢您的帮助。


1
@smci,你的示例中有一个拼写错误。符号应该放在from参数上,例如:lambda = 10^seq(from=-10, to=15, by=1/3) - Faris
@smci,你有这个建议的引用吗?我找不到任何声明不要使用默认lambda序列的内容。虽然我理解为什么提供用户指定的序列可能是好的,但我希望能够找到一个来源。 - AW27
3个回答

23

试一试:

fit = glmnet(as.matrix(mtcars[-1]), mtcars[,1], 
    lambda=cv.glmnet(as.matrix(mtcars[-1]), mtcars[,1])$lambda.1se)
coef(fit)

或者你可以在coef中指定一个lambda值:

fit = glmnet(as.matrix(mtcars[-1]), mtcars[,1])
coef(fit, s = cv.glmnet(as.matrix(mtcars[-1]), mtcars[,1])$lambda.1se)

你需要选择一个“最佳”的lambda,lambda.1se是一个合理或可辩解的选择。但你也可以使用cv.glmnet(as.matrix(mtcars[-1]), mtcars[,1])$.lambda.min或者其他你认为对你来说最好的lambda。


cv.glmnet 的 lambda.min 的对数为 -0.5。如果我在 glmnet 的拟合图上标记 x 轴上的这个点,可以吗?该图的 x 轴上指示的对数 lambda 是否来自与 lambda.min 相同的向量? - rnso
1
x轴上的log lambda来自于与lambda.min相同的lambda值向量。请注意,由于交叉验证的性质,如果您再次运行cv.glmnet,可以得到不同的lambda.min值。因此,您在x轴上的标记将是特定调用cv.glmnet的lambda.min。 - Jota
1
需要注意的一点是,正如Frank所说,如果您重新运行交叉验证,最小lambda会有一些(或很多)变化。?cv.glmnet提示*还要注意的是,cv.glmnet的结果是随机的,因为折叠是随机选择的。用户可以通过多次运行cv.glmnet并平均误差曲线来减少这种随机性。*。我重新运行了100次cv并平均曲线,然后找到了这个平均曲线的最小值(或者如果您喜欢,是1se)。 - user2957945
1
@smci 也许在交叉验证上询问是个好主意?我认为你的想法听起来很合理,但我也会说“最佳实践”可能取决于你的目标。你追求简洁性吗?预测能力?特征选择? - Jota
1
@smci,我的做法是使用一个随机种子:但是使用一个外部循环,以便运行多次(N)的交叉验证。这将产生N个lambda by mse曲线。然后我在每个lambda处对曲线上的N个mse进行平均。然后找到使这个平均mse最小的lambda。 - user2957945
显示剩余6条评论

4
为了提取最佳的lambda值,您可以键入fit$lambda.min
要获得与最佳lambda值对应的系数,请使用coef(fit, s = fit$lambda.min) - 请参考Glmnet手册的第6页。
我认为系数是由适合于完整数据而不仅仅是测试集的模型产生的,就像在此页面中提到的那样。

欢迎来到SO!有时候我们可以超越仅仅回答问题的范畴,还可以提供关于如何更好地解决问题的建议。在这种情况下,考虑指向“glmnet”小册子或cv.glmfit函数,这将帮助他们找到一个更好的lambda值以实现更好的泛化效果。 - rcorty
嘿,如果你执行fit = glmnet(as.matrix(mtcars[-1]), mtcars[,1]),那么就没有fit$lambda.min。只有通过调用cv.glmnet(as.matrix(mtcars[-1]), mtcars[,1])才能得到它。 - StupidWolf
另外,如果您阅读上面接受的答案,可以使用lambda.min,但通常使用lambda.1se,因为您尝试选择更简约的模型。https://stats.stackexchange.com/questions/138569/why-is-lambda-within-one-standard-error-from-the-minimum-is-a-recommended-valu - StupidWolf

-2

boxcox(){MASS}函数提供了一个最大似然图,显示在线性模型中哪个l值提供了最佳拟合

boxcox(lm.fit)函数为线性模型中一系列l值提供了最大似然图

lm.fit函数选择具有最高ML值的l值

boxcox(lm.fit,lambda=seq(-0.1, 0.1, 0.01))如果例如,最高的l值约为0.04,则在该区域周围获得一个放大的图形

在此示例中,该函数提供了一个在-0.1和0.1之间以0.01为增量的l值的图形。


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