glmnet的公式接口

Hon*_*Ooi 15 r formula glmnet

在过去的几个月里,我参与了许多项目,在这些项目中,我使用了这个glmnet包,以适应弹性网模型.它很棒,但与大多数R建模功能相比,界面相当简陋.特别是,您必须提供响应向量和预测矩阵,而不是指定公式和数据框.你也会失去常规界面提供的许多生活质量的东西,例如对因子的敏感(?)处理,缺失值,将变量放入正确的顺序等等.

所以我通常最终编写自己的代码来重新创建公式/数据框架界面.由于客户机密性问题,我最终还是留下了这个代码,不得不再次为下一个项目编写代码.我想我也可以咬紧牙关并创建一个实际的包来做到这一点.但是,在我这样做之前有几个问题:

  • 使用具有弹性网络模型的公式/数据框架界面是否存在任何问题?(我知道标准化和虚拟变量,宽数据集可能需要稀疏模型矩阵.)
  • 有没有现成的包呢?

Hon*_*Ooi 23

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

或者在R中,使用devtools::install_github:

install.packages("devtools")
library(devtools)
install_github("hong-revo/glmnetUtils")
library(glmnetUtils)
Run Code Online (Sandbox Code Playgroud)

从自述文件:

一些生活质量功能简化了弹性网模型的拟合过程glmnet,具体为:

  • glmnet.formula提供公式/数据框架接口glmnet.
  • cv.glmnet.formula做类似的事情cv.glmnet.
  • 上述方法predict和方法coef.
  • 一个函数cvAlpha.glmnet,通过交叉验证选择alpha和lambda参数,遵循帮助页面中描述的方法cv.glmnet.可选地并行进行交叉验证.
  • 方法plot,predictcoef针对上述.

顺便说一句,在写上述内容时,我想我已经意识到为什么之前没有人这样做过.R处理模型框架和模型矩阵的核心是一个terms对象,它包括一个矩阵,每个变量一行,每个主效果和交互一列.在效果上,这(至少)大致为p X p矩阵,其中p是在模型中的变量数.当p为16000时(这些日子常见的是宽数据),得到的矩阵大小约为1千兆字节.

尽管如此,我还没有遇到任何与这些对象有关的问题.如果它成为一个主要问题,我会看看我是否能找到解决方法.


2016年10月更新

我已经推动了对回购的更新,以解决上述问题以及与因素相关的问题.从文档:

glmnetUtils有两种方法可以从公式和数据框中生成模型矩阵.第一种是使用包含model.frame和的标准R机械model.matrix; 第二个是一次构建一个变量矩阵.下面讨论和对比这些选项.

使用model.frame

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

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

标准R方法的另一个问题是因素的处理.通常,model.matrix将N级因子转换为具有N-1列的指示符矩阵,其中一列被删除.这对于非正规模型来说是必要的,因为整组N列是线性相关的,因此与lm和glm一致.对于通常的治疗对比,解释是丢弃的列表示基线水平,而其他列的系数表示响应相对于基线的差异.

这可能不适合适合glmnet的正则化模型.正则化过程将系数缩小到零,这迫使与基线的估计差异更小.但这只有在预先选择基线水平或其他有意义的默认情况下才有意义; 否则它有效地使水平更接近于任意选择的水平.

手动构建模型矩阵

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

不使用的主要缺点model.frame是公式只能相对简单.目前,只有直截了当的公式y ~ x1 + x2 + ... + x_p由代码处理,其中x是已存在于数据中的列.不支持交互术语和计算表达式.在可能的情况下,您应事先计算此类表达式.


2017年4月更新

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

  • @rhombidodecahedron谢谢.我没有设置默认的alpha,因为它似乎很难选择一个合适的值:(2-D)交叉验证表面可能相当嘈杂,特别是对于小而宽的数据集.您可以做的是查看每个alpha值的绘制CV曲线,并选择能够获得最佳结果的CV曲线. (2认同)