我有一个函数,如下所示,它将类型为X
的设计矩阵big.matrix
作为输入并预测响应。
注意:矩阵X
的大小超过10 GB。所以我无法将其加载到内存中。我使用read.big.matrix()
生成了支持文件X.bin
和X.desc
。
myfun <- function(X) {
## do something with X. class(X) == 'big.matrix'
}
我的问题是,如何通过这个庞大的big.matrix有效地进行交叉验证?
我的尝试:(虽然有效但很耗时。)
idx.train
和测试idx.test
的索引; X
划分为X.train
和X.test
。由于X.train
和X.test
也非常大,我必须将它们存储为big.matrix
,并为培训创建关联的支持文件(.bin
,.desc
)和测试集每次折叠。 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
答案 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个不同的矩阵,您可以根据需要使用这些矩阵。