【问题标题】:How does glmnet compute the maximal lambda value?glmnet 如何计算最大 lambda 值?
【发布时间】:2014-10-05 03:18:06
【问题描述】:

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

包 vignette (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 进行逻辑回归?

【问题讨论】:

    标签: r glmnet lasso-regression


    【解决方案1】:

    根据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 代码计算得出的。

    【讨论】:

    • 谢谢,我知道最大 lambda 是系数为零的最小值。我也试过浏览 GitHub 上的 fortran 代码,不幸的是 Fortran 对我来说太陌生了,我完全看不懂...
    【解决方案2】:

    要获得相同的结果,您需要使用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
    

    【讨论】:

    • 这里回答了问题的第二部分吗?
    • 这似乎只回答了 lambda 路径的计算,因为 x 和 y 是事先按比例缩放的。给定 x 和 y 时,如何计算 lambda 路径?
    【解决方案3】:

    关于第二个问题,请参阅 Friedman 等人的论文,"Regularization paths for generalized linear models via coordinate descent"。特别是,参见方程(10),它是平衡时的平等。只需检查在什么条件下所有参数的分子 $S(\cdot,\cdot)$ 都为零。

    【讨论】:

      【解决方案4】:

      逻辑回归的 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
      

      【讨论】:

        【解决方案5】:

        抱歉,已经有一段时间了,但也许还有帮助:

        您可以通过在完全正则化模型的优化参数值(例如. 所有惩罚参数设置为零)。

        不过,遗憾的是,我无法帮助解决价值观的差异。虽然我可以说我尝试使用比计算出的最大 lambda 略高的最大 lambda 值(例如 5%),但所有选定参数受约束的模型肯定会成为估计模型数量的一部分。也许这就是 glmnet 正在做的事情。

        编辑:抱歉,我将非正则化模型与完全惩罚模型混淆了。现在在上面编辑它。

        【讨论】:

          猜你喜欢
          • 2023-01-14
          • 2017-12-05
          • 1970-01-01
          • 2021-12-21
          • 2012-10-14
          • 1970-01-01
          • 1970-01-01
          • 2013-11-17
          • 1970-01-01
          相关资源
          最近更新 更多