20

在过去的几个月里,我参与了许多项目,我使用该glmnet软件包来拟合弹性网络模型。这很棒,但与大多数 R 建模功能相比,界面相当简单。特别是,您必须给出响应向量和预测矩阵,而不是指定公式和数据框。您还失去了常规界面提供的许多生活质量方面的东西,例如对因素的明智 (?) 处理、缺失值、将变量按正确顺序排列等。

所以我通常最终编写了自己的代码来重新创建公式/数据框接口。由于客户保密问题,我最终也留下了这段代码,不得不为下一个项目重新编写它。我想我不妨硬着头皮创建一个实际的包来做到这一点。但是,在我这样做之前有几个问题:

  • 使用带有弹性网络模型的公式/数据框接口是否存在任何复杂的问题?(我知道标准化和虚拟变量,宽数据集可能需要稀疏模型矩阵。)
  • 是否有任何现有的软件包可以做到这一点?
4

1 回答 1

31

好吧,看起来没有预先构建的公式界面,所以我继续制作自己的。您可以从 Github 下载:https ://github.com/Hong-Revo/glmnetUtils

或在 R 中,使用devtools::install_github

install.packages("devtools")
library(devtools)
install_github("hong-revo/glmnetUtils")
library(glmnetUtils)

从自述文件:

一些生活质量函数可简化使用 拟合弹性网络模型的过程glmnet,特别是:

  • glmnet.formula提供一个公式/数据框接口到glmnet.
  • cv.glmnet.formula为 .做类似的事情cv.glmnet
  • predict上述两种方法coef
  • 一个cvAlpha.glmnet通过交叉验证选择 alpha 和 lambda 参数的函数,遵循cv.glmnet. 可选择并行进行交叉验证。
  • 的方法plotpredict以及coef上述方法。

顺便说一句,在写以上内容时,我想我意识到为什么以前没有人这样做过。R 处理模型框架和模型矩阵的核心是一个terms对象,它包括一个矩阵,每个变量一行,每个主效应和交互作用一列。实际上,这(至少)大致是一个p x p矩阵,其中p是模型中的变量数。当p为 16000 时(这在当今广泛数据中很常见),生成的矩阵大小约为 1 GB。

尽管如此,我在使用这些对象时(还)还没有遇到任何问题。如果它成为一个主要问题,我会看看我是否能找到解决方法。


2016 年 10 月更新

我已经向 repo 推送了更新,以解决上述问题以及与因素相关的问题。从文档中:

glmnetUtils 可以通过两种方式从公式和数据框生成模型矩阵。第一种是使用标准 R 机器,包括model.framemodel.matrix; 第二个是一次构建一个变量的矩阵。这些选项将在下面讨论和对比。

使用模型框架

这是更简单的选项,也是与其他 R 建模功能最兼容的选项。该model.frame函数接受一个公式和数据框并返回一个模型框:一个带有特殊信息的数据框,它可以让 R 理解公式中的术语。例如,如果公式包含交互项,则模型框架将指定数据中的哪些列与交互相关,以及应如何处理它们。同样,如果公式包含RHS 上的exp(x)或类似的表达式,将评估这些表达式并将它们包含在输出中。I(x^2)model.frame

使用的主要缺点model.frame是它会生成一个术语对象,该对象对变量和交互的组织方式进行编码。该对象的属性之一是一个矩阵,每个变量一行,每个主效应和交互作用一列。至少,这是(大约)apxp 方阵,其中 p 是模型中主效应的数量。对于 p > 10000 的宽数据集,该矩阵的大小可能接近或超过千兆字节。即使有足够的内存来存储这样的对象,生成模型矩阵也可能需要大量时间。

标准 R 方法的另一个问题是因素的处理。通常,model.matrix会将 N 级因子转换为具有 N-1 列的指示矩阵,其中删除一列。这对于适合 lm 和 glm 的非正则化模型是必要的,因为 N 列的完整集是线性相关的。对于通常的处理对比,解释是删除的列表示基线水平,而其他列的系数表示响应相对于基线的差异。

这可能不适合适合 glmnet 的正则化模型。正则化过程将系数缩小到零,这迫使估计的与基线的差异更小。但这只有在事先选择了基线水平时才有意义,或者作为默认值有意义;否则,它实际上使级别更类似于任意选择的级别。

手动构建模型矩阵

为了解决上述问题,glmnetUtils 默认会避免使用model.frame,而是逐项构建模型矩阵。这避免了创建terms对象的内存成本,并且可以明显比标准方法快。它还将在模型矩阵中包含一列,用于一个因子的所有级别;也就是说,没有假设基线水平。在这种情况下,系数代表与整体平均响应的差异,将它们缩小到零是有意义的(通常)。

不使用的主要缺点model.frame是公式只能比较简单。目前,y ~ x1 + x2 + ... + x_p代码只处理简单的公式,其中 x 是数据中已经存在的列。不支持交互项和计算表达式。在可能的情况下,您应该事先计算这些表达式。


2017 年 4 月更新

经过几次打嗝,这终于在 CRAN 上。

于 2015-04-01T05:05:58.177 回答