如何在 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.bin
和X.desc
。
myfun <- function(X)
## do something with X. class(X) == 'big.matrix'
我的问题是,如何使用这个巨大的 big.matrix 有效地进行交叉验证?
我的尝试:(有效,但耗时。)
第 1 步:对于每一折,获取训练索引idx.train
和测试idx.test
;
第二步:将X
分为X.train
和X.test
。由于X.train
和X.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 的 row() 和 col()