glmnet 系数因版本而异(2.0.16 与 3.0.2)

glmnet coefficients differ between versions (2.0.16 vs 3.0.2)

我管理着一个严重依赖 glmnet 包的内部代码库。升级到最新版本 (v3.0.2) 后,我的单元测试开始因 Cox 模型的系数而失败。 glmnet 的先前版本是 v2.0.16 (R 3.5.2)。我现在运行 R v3.6.2.

我注意到有一个新的 relax = 参数似乎在路径中使用了非正则化拟合,我想这 可能 会导致轻微的适合度不同,但默认值为 relax = FALSE,所以我怀疑这是问题所在。

下面是一个基于mtcars数据集的reprex,拟合2个随机选择的特征,并将两个变量重命名为timestatus,以便拟合考克斯模型。正确的 reprex 比较很困难,因为它需要不同的 R 安装,但这应该允许任何人重现该问题。

library(magrittr)
library(dplyr)
library(glmnet)
dat <- mtcars %>%
    select(mpg, disp, status = vs, time = hp) %>%   # select 2 features; assign time & status
    mutate_at(1:2, ~ {
      log10(.x) %>% subtract(mean(.)) %>% divide_by(sd(.))   # center & scale
    }) %>% as.matrix()
glmnet(dat[, 1:2], dat[, 3:4], family = "cox", lambda = 0)$beta   # fit model

v3.0.2 的结果是:

#> 2 x 1 sparse Matrix of class "dgCMatrix"
#>              s0
#> mpg   0.2293535
#> disp -1.8160387

v2.0.16 的结果是:

#> 2 x 1 sparse Matrix of class "dgCMatrix"
#>              s0
#> mpg   0.2154324
#> disp -1.8172714

其他人是否注意到类似的差异?我有点惊讶没有发现其他人遇到同样的问题。我是否必须更新我所有的单元测试:(

见解and/or 非常感谢解释。 提前致谢。

评论有点太长了:

  • 我在 Ubuntu 16.04 上重现了你的结果(使用 devtools::install_version(),见下文)。
  • 2.0-16 到 3.0-2 跨越多个版本(以及多个内部标记的未发布版本):NEWS filecoxnet 进行了多次引用(大概是内部函数调用 family="cox":

    • 2.0-20:

      • Fixed a bug in internal function coxnet.deviance to do with input pred, as well as saturated loglike (missing) and weights
      • added a coxgrad function for computing the gradient
    • 2.0-19: Fixed a bug in coxnet to do with ties between death set and risk set
我建议使用
devtools::install_version("glmnet",version=...,lib=<version-specific>)

安装从 2.0-16 到 3.0-2 的每个版本,每个版本都在一个单独的库中,以便于(通过 library("glmnet", lib.loc=...)加载不同的包版本并一分为二以找到特定的更改。 (中间版本未发布,因此您将从 2.0-18 跳到 3.0。)

我猜测这些 coxnet 错误修复之一(有意或作为副作用)导致了更改。

如果它在可访问的 git 存储库中,您可以使用 git bisect 和本地副本来自动执行该过程(对于如此少量的更改点,这可能不值得,但它不看起来开发树不可用:有一个很好的 pkgdown website 但我没有看到任何指向版本控制系统的链接。

如果您手上有很多时间,您可以下载所有存档的 tarball 并在其中寻找更改...