【问题标题】:Getting glmnet coefficients at 'best' lambda获得“最佳” lambda 的 glmnet 系数
【发布时间】:2015-08-14 10:30:39
【问题描述】:

我在 glmnet 中使用以下代码:

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

但是,我想打印出最好的 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 和相应的系数。感谢您的帮助。

【问题讨论】:

  • 您正在使用默认的 lambda 序列,它是使用 nlambda,lambda.min.ratio 构造的。我一直听到的建议是传递你自己的 lambda 序列,例如lambda = 10^seq(10,-15,1/3) 或类似的。
  • @smci ,您的示例中有错字。标志应该在 from 参数上,例如lambda = 10^seq(from=-10, to=15, by=1/3)
  • @smci 你有引用的建议吗?我找不到任何声明不使用默认 lambda 序列的内容。虽然我理解为什么提供一个用户指定的文件可能会很好,但我还是希望有一个来源。
  • @AW27:你有already been asking me this on CV for a week 没有引用,但我告诉你十多年来整个用户社区都知道什么是正确的方法;我既不是 glmnet doc 的作者,也不是出版者。所以无论如何,我鼓励你提出一个 docbug,写一篇博客文章来说明这一点(在多个不同的数据集上),做一个文献搜索为什么这没有很好的覆盖等等。但是请不要再问我了.

标签: r regression glmnet coefficients


【解决方案1】:

试试这个:

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 在 plot(fit) 的 x 轴上标记这个点,可以吗?该图的 x 轴上指示的 log lambda 来自 lambda.min 所在的同一向量?
  • x 轴上的对数 lambda 与 lambda.min 来自同一个 lambda 值向量。请注意,由于交叉验证的性质,如果再次运行 cv.glmnet,您可以获得不同的 lambda.min 值。因此,您在 x 轴上的标记将是来自特定调用 cv.glmnetlambda.min
  • 有一点需要注意,正如 Frank 所说,如果重新运行交叉验证,最小 lambda 会有一些(或很多)变化。 ?cv.glmnet 提示 ` 还要注意 cv.glmnet 的结果是随机的,因为折叠是随机选择的。用户可以通过多次运行 cv.glmnet 并平均误差曲线来减少这种随机性。`.我重新运行 cv 100 次并对曲线进行平均,然后找到该平均曲线的最小值(如果您愿意,也可以找到 1se)。
  • @smci 也许询问 Cross Validated 是个好主意?我会说你的想法听起来很合理,但我也会说“最佳实践”可能取决于你的目标。你要吝啬吗?预测能力?特征选择?
  • @smci,我所做的是使用一个随机种子:但使用外部循环,以便 cv 运行多次(N)次。这会产生 N lambda by mse 曲线。然后我在每个 lambda 的曲线上平均 N ms'se。然后找到最小化这个平均 mse 的 lambda。
【解决方案2】:

要提取最佳 lambda,您可以输入 fit$lambda.min

要获得与最佳 lambda 对应的系数,请使用 coef(fit, s = fit$lambda.min) - 请参考 Glmnet vignette 的第 6 页。

我认为系数是由适合完整数据的模型产生的,而不仅仅是测试集,正如page 中提到的那样。

【讨论】:

  • 欢迎来到 SO!我们有时可以不只是回答问题,还可以包括关于提问者如何做得更好的建议。在这种情况下,请考虑将提问者指向“glmnet”小插图或cv.glmfit 函数,这将帮助他们找到可以更好地泛化的 lambda 值。
  • 嘿,如果你做 fit = glmnet(as.matrix(mtcars[-1]), mtcars[,1]),就没有 fit$lambda.min。你只能通过调用 cv.glmnet(as.matrix(mtcars[-1]), mtcars[,1])
  • 另外,如果您阅读上面接受的答案,可以使用 lambda.min,但 lambda.1se 是常用的,因为您尝试选择更简约的模型。 stats.stackexchange.com/questions/138569/…
【解决方案3】:

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

boxcox(lm.fit) 提供了一个最大似然图 线性模型中的大范围 l

lm.fit 选择 l 和 最高ML值

boxcox(lm.fit,lambda=seq(-0.1, 0.1, 0.01)) 如果,对于 例如,最高的 l 大约是 0.04,得到一个放大的情节 那个区域

在示例中,函数提供了 l =- 之间的绘图 0.1 和 0.1,增量为 0.01。

【讨论】:

    猜你喜欢
    • 2017-12-25
    • 2020-09-22
    • 2014-07-23
    • 2014-10-05
    • 2018-06-13
    • 2013-09-08
    • 2018-06-20
    • 2023-04-08
    • 2015-07-14
    相关资源
    最近更新 更多