glmnet交叉验证与分组数据

时间:2017-02-24 14:25:55

标签: r group-by glmnet

我正在使用glmnet进行网络数据。通常,数据是分类的(因子的高基数)并且具有数百万个样本。我正在处理大数据'并希望内存效率

因为它是分类的,所以可以通过分组并传递每个组的成功和失败次数来更有效地表示数据:例​​如,男性' 30-35' :30次成功,50次失败

我面临的问题是交叉验证...通过分组我不能只对数据集进行分区(调用X原始分组数据集)。我想要的是能够传递原始的分组数据独立变量,然后分割整个折叠的结果:例如30次成功50次失败将分成10#成功,#failure对(复制如果我对原始未分组数据进行交叉验证会发生什么。无论如何以这种方式运行cv.glmnet?复制所有数据k次(具有不同的成功失败值)的替代方案显然是内存效率较低。

假设我有2组和2折:

男性'' 30-35' :30次成功,50次失败

女性'' 30-35' :50次成功,30次失败

然后我想要的是

X = 

    [[male','30-35'] 

    [female','30-35']]

y = 

[[20,30], [10,20],

[[25,30], [25, 0] ]

因此X变量包含n个组。因变量然后有n行,并且有2列(每列包含成功失败元组) - 每列代表一个折叠。现在我并不是说我追求这个特定的数据结构,只是对于分组数据,我不想创建一个k N行X_fold矩阵和相应的y_fold矩阵,其中k N行。

即X_fold =

[['male','30-35',...] 

['female','30-35',...]

['male','30-35',...] 

['female','30-35',...]
]

和y_fold =

[[20,30], ,
[25,30], 
[10,20]
[25, 0] ]

关键是X有很多行和列,当独立数据相同时,我不想复制它,只有成功和失败的次数发生变化(允许折叠成功0次,0次成功失败) )

我假设如果不修改源代码就无法做到这一点,但是想要仔细检查没有其他人遇到过这个问题。

1 个答案:

答案 0 :(得分:0)

你提到交叉验证,但这不是问题。您想要的是,当您的所有变量都是分类时,将您的数据集汇总到一个偶然的因子表中,并使模型符合响应和非响应的计数。这是逻辑回归中相当着名的技术。它既适用于拟合基础模型,也适用于交叉验证。

要了解它是如何工作的,让我们生成一个示例数据集(100万行):

set.seed(12345)
df <- data.frame(
    x1 = factor(sample(10, 1e6, TRUE)),
    x2 = factor(sample(20, 1e6, TRUE)),
    x3 = factor(sample(5, 1e6, TRUE)),
    x4 = factor(sample(15, 1e6, TRUE)),
    y = rbinom(1e6, 1, 0.1))

现在将其折叠到列联表(15000个单元格/行):

library(dplyr)
dfsmry <- df %>%
    group_by(x1, x2, x3, x4) %>%
    summarise(y = sum(y), ny = n() - y)

现在适合弹性网模型。将逻辑回归拟合到汇总数据时,响应是一个2列矩阵,其中包含每个单元格中的总失败和成功。

# to make life easier: see https://github.com/hong-revo/glmnetUtils
library(glmnetUtils)

# base model
mod <- glmnet(cbind(ny, y) ~ x1 + x2 + x3 + x4, data = dfsmry, family = "binomial")

# do crossvalidation
cvmod <- cv.glmnet(cbind(ny, y) ~ x1 + x2 + x3 + x4, data = dfsmry, family = "binomial")