【问题标题】:glmnet - variable importance?glmnet - 变量的重要性?
【发布时间】:2016-05-29 11:03:07
【问题描述】:

我正在使用 glmnet 包执行 LASSO 回归。有没有办法获得所选择的各个变量的重要性?我考虑过对通过 coef(...) 命令获得的系数进行排名(即,与零的距离越大,变量就越重要)。这会是一种有效的方法吗?

感谢您的帮助!

cvfit = cv.glmnet(x, y, family = "binomial")
coef(cvfit, s = "lambda.min")

## 21 x 1 sparse Matrix of class "dgCMatrix"
##                    1
## (Intercept)  0.14936
## V1           1.32975
## V2           .      
## V3           0.69096
## V4           .      
## V5          -0.83123
## V6           0.53670
## V7           0.02005
## V8           0.33194
## V9           .      
## V10          .      
## V11          0.16239
## V12          .      
## V13          .      
## V14         -1.07081
## V15          .      
## V16          .      
## V17          .      
## V18          .      
## V19          .      
## V20         -1.04341

【问题讨论】:

  • glmnet 缩放输入变量,因此在某种意义上,您选择具有最高“缩放效果”的变量。不知何故,它应该很重要,并且有一些论文实际上试图解决这个特定问题(Hastie and Tibshirani 最近的书也讨论了这个问题)。但是,这确实是 StackExchange 的问题

标签: r glmnet


【解决方案1】:

caret 包中就是这样完成的。

总而言之,您可以取最终系数的绝对值并对它们进行排名。排名系数是您的变量重要性。

要查看源代码,可以输入

caret::getModelInfo("glmnet")$glmnet$varImp

如果您不想使用caret 包,可以从包中运行以下行,它应该可以工作。

varImp <- function(object, lambda = NULL, ...) {

  ## skipping a few lines

  beta <- predict(object, s = lambda, type = "coef")
  if(is.list(beta)) {
    out <- do.call("cbind", lapply(beta, function(x) x[,1]))
    out <- as.data.frame(out, stringsAsFactors = TRUE)
  } else out <- data.frame(Overall = beta[,1])
  out <- abs(out[rownames(out) != "(Intercept)",,drop = FALSE])
  out
}

最后,根据需要调用函数。

varImp(cvfit, lambda = cvfit$lambda.min)

【讨论】:

  • 我认为 glmnet 包会产生非标准化的系数。
  • @Boxuan 感谢您为glmnet 模型计算varImp 的代码。但是变量重要性值大于 1。但是当我们从 caret 包中实现 varImp 时,它的范围始终为 0-1。你能回复一下吗?
  • @BappaDas 你能分享一个可重现的例子吗?我的代码几乎与原始的 caret 代码相同,所以我不明白为什么会有差异。
  • @Boxuan 请访问question,您将在其中找到可重现的示例。
  • 当我尝试运行此代码时,我收到错误no applicable method for varImp applied to an object of class "cv.glmnet"
【解决方案2】:

使用 cv.glmnet 对象的内容来创建系数的有序列表非常容易...

coefList <- coef(cv.glmnet.MOD, s='lambda.1se')
coefList <- data.frame(coefList@Dimnames[[1]][coefList@i+1],coefList@x)
names(coefList) <- c('var','val')

coefList %>%
  arrange(-abs(val)) %>%
  print(.,n=25)

注意:正如其他发帖人所评论的那样...要获得类似的比较,您需要在建模步骤之前对数值变量进行缩放/z 评分...否则可以将大系数值分配给具有一个非常小的比例,即范围(0,1),当放置在具有非常大比例的变量的模型中时,即范围(-10000,10000),这将意味着您对系数值的比较不是相对的,因此在大多数情况下毫无意义。

【讨论】:

    【解决方案3】:

    在比较系数的大小之前,您应该通过将每个系数乘以相应预测变量的标准差来对它们进行归一化。这个答案有更详细和有用的链接: https://stats.stackexchange.com/a/211396/34615

    【讨论】:

      猜你喜欢
      • 2016-09-29
      • 2021-02-14
      • 2021-01-07
      • 2021-01-04
      • 2020-03-31
      • 1970-01-01
      • 2015-07-25
      • 2016-07-05
      • 2015-12-23
      相关资源
      最近更新 更多