如何有效地与R中的big.matrix进行交叉验证?

时间:2015-11-09 17:49:15

标签: r bigdata cross-validation r-bigmemory

我有一个函数,如下所示,它将类型为X的设计矩阵big.matrix作为输入并预测响应。

注意:矩阵X的大小超过10 GB。所以我无法将其加载到内存中。我使用read.big.matrix()生成了支持文件X.binX.desc

myfun <- function(X) {
## do something with X. class(X) == 'big.matrix'
}

我的问题是,如何通过这个庞大的big.matrix有效地进行交叉验证?

我的尝试:(虽然有效但很耗时。)

  • 第1步:每次折叠,获取培训idx.train和测试idx.test的索引;
  • 第2步:将X划分为X.trainX.test。由于X.trainX.test也非常大,我必须将它们存储为big.matrix,并为培训创建关联的支持文件(.bin.desc)和测试集每次折叠
  • 第3步:提供X.train以构建模型,并预测X.test的响应。

耗时的部分是第2步,我必须多次创建用于训练和测试的后备文件(几乎像复制/粘贴原始大矩阵)。例如,假设我进行了10次交叉验证。步骤2将花费30多分钟来创建所有10个折叠的后备文件!

要在第2步中解决这个问题,我想也许我可以将原始矩阵分成10个子矩阵(类类型big.matrix)一次。然后对于每个折叠,我使用一个部分进行测试,将剩余的9个部分组合为一个用于训练的大矩阵。但是新问题是,没有复制/粘贴,就无法有效地将小big.matrix组合成更大的X

当然,我可以为这个交叉验证程序进行分布式计算。但我只是想知道如果只使用一个核心,是否有更好的方法来加快程序。

有什么想法吗?提前谢谢。

更新

事实证明,当mpermute()非常大时,@ cdeterman的答案并不起作用。原因是mpermute()函数基本上通过复制/粘贴来置换行。 ReorderRNumericMatrix()在C ++中调用reorder_matrix(),然后调用mongoose.connect('mongodb://username:password@host:port/database') 函数。此函数通过循环遍历所有列和行并执行复制/粘贴来重新排序矩阵。请参阅源代码here

有没有更好的想法来解决我的问题?感谢。

END UPDATE

1 个答案:

答案 0 :(得分:3)

您需要使用sub.big.matrix功能。这避免了任何进一步的复制并指向相同的原始数据。但是,它目前只能对连续的行进行子集化。因此,您首先需要置换行。

# Step 1 - generate random indices
idx <- sample(nrow(X), nrow(X))
mpermute(X, idx)

# Step 2 - create your folds
max <- nrow(bm)/10 # assuming 10 folds
idx_list <- split(seq(nrow(bm)), ceiling(seq(nrow(bm))/max))

# Step 3 - list of sub.big.matrix objects
sm_list <- lapply(idx_list, function(x) sub.big.matrix(bm, firstRow = x[1], lastRow = x[length(x)]))

您现在可以将原始big.matrix拆分为10个不同的矩阵,您可以根据需要使用这些矩阵。