如何在 R 中有效地使用 big.matrix 进行交叉验证?

Posted

技术标签:

【中文标题】如何在 R 中有效地使用 big.matrix 进行交叉验证?【英文标题】:How to efficiently do cross-validation with big.matrix in R? 【发布时间】:2015-11-09 17:49:15 【问题描述】:

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

注意:矩阵 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; 第二步:将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 有效地组合成一个更大的big.matrix,而不需要复制/粘贴。

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

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

更新:

事实证明,当X 非常大时,@cdeterman 的答案不起作用。原因是mpermute() 函数本质上是通过复制/粘贴来置换行。 mpermute() 在 C++ 中调用 ReorderRNumericMatrix(),然后调用 reorder_matrix() 函数。此函数通过遍历所有列和行并进行复制/粘贴来重新排序矩阵。见源代码here。

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

结束更新

【问题讨论】:

【参考方案1】:

您将需要使用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 个不同的矩阵,您可以随意使用。

【讨论】:

谢谢@cdeterman。这真的很高兴知道。但是,这并不能完全解决问题。我还得想办法把 9 个子 big.matrix 合二为一进行训练。 或者,根据您的建议,我似乎每次都可以mpermute 矩阵,方法是将测试部分(其中 idx == fold id)放在底部,然后可以使用sub.big.matrix获得培训和测试部分。但由于mpermute 更改了原始矩阵,这似乎也无法正常工作。 如果我不断更新mpermute 中使用的索引向量,第二种方法似乎可行。非常感谢@cdeterman。 嗨@cdeterman,事实证明你的方法不起作用,因为mpermute() 需要很长时间。我想知道您是否对这个问题有其他想法。非常感谢。 @AaronZeng 在这一点上,这可能仍然是最好的解决方案。这可能需要一段时间,但至少它适合您的 RAM,并且您最终可以拆分矩阵。目前不支持非连续子集。随时提交问题here

以上是关于如何在 R 中有效地使用 big.matrix 进行交叉验证?的主要内容,如果未能解决你的问题,请参考以下文章

如何释放崩溃 R 会话的 big.matrix 对象使用的内存

在 R 中计算 big.matrix 的行总和?

等效于 R 中 big.matrix 的 row() 和 col()

R中几个big.matrix对象的元素平均值

R bigmemory attach.big.matrix 对于非常宽的矩阵来说非常慢

如何转置 big.matrix 对象?