0

在过去的几天里,我一直在发布一个问题,我需要创建一个 7000x7000 距离矩阵。在内存上做这一切给了我无法分配向量错误。我使用的是 Windows XP SP 3、3GB RAM、32 位系统。我原本想使用 bigmemory 库,但它似乎不适用于 Windows。我已经在 上做了一些阅读ff package,所以这是我到目前为止的想法:

require(ff)    
ffmat <- ff(vmode="double", dim=c(7000,7000))
ffmat <- as.matrix(dist(data[1:7000, ], diag=TRUE, upper=TRUE))

问题是我仍然遇到向量分配错误。请注意dim(data)= 7000x182(很多变量)。

进行验尸gc()会使memory.size()背部恢复到正常水平。就好像 R 在写入创建的 ff 之前将结果存储在内存中。有没有办法解决?

4

3 回答 3

0

“就好像 R 在写入创建的 ff 之前将结果存储在内存中。有什么办法解决这个问题吗?”

这正是 R 正在做的事情。编写代码的方式有两件事:它创建一个ff对象,然后用as.matrix.

您可能会扩展该dist函数以使用ff对象,或者编写您自己的dist使用实现ff

于 2013-05-28T17:44:24.790 回答
0

非常感谢 jwijffels 引导我朝着正确的方向前进,并感谢 http://rmazing.wordpress.com/2013/02/22/bigcor-large-correlation-matrices-in-r/ 让我朝着正确的方向开始。

假设一个 7000x180 的数据矩阵称为training.data. 目标是创建一个尺寸为 7000x7000 的对称距离矩阵。实际上,使用daisy()创建了一个不同的度量,但它是相似的逻辑。

distff <- function(training.data, nblocks=5, verbose=TRUE) {
  require(ff)
  require(cluster)
  ffmat <- ff(vmode="single", dim=c(7000,7000), filename="if so desired")
  nro <- nrow(training.data)
  ### This could be changed to handle rowcounts that have 
  ### modulus(nro/nblocks) != 0
  splt <- split(1:nro, rep(1:nblocks, each = nro/nblocks))
  COMBS <- expand.grid(1:length(splt), 1:length(splt)) 
  COMBS <- t(apply(COMBS, 1, sort)) 
  COMBS <- unique(COMBS) 
  for (i in 1:nrow(COMBS)) {
    COMB <- COMBS[i,]
    ### Since g1 and g2 get appended below, it wouldn't make sense to append the
    ### same group to itself
    if (COMB[1] != COMB[2]) {
      g1 <- splt[[COMB[1]]]
      g2 <- splt[[COMB[2]]]
      slj <- as.matrix(daisy(training.data[c(g1,g2),], metric="gower", 
                             stand=FALSE))
      ffmat[c(g1,g2), c(g1,g2)] <- slj
      rm(slj)
      gc()
    }
  }
}

而已。我意识到有一些效率低下(比如多次编写几个组)。我没关系,因为它有效。就像我说的,这段代码的大部分是从上面引用的网站借用和定制的。

于 2013-05-30T19:41:10.080 回答
0

您可能需要将任务分解为多个部分并将各个部分分配给矩阵,而不是一步完成。

distandas.matrix函数不知道结果将是一个 ff 对象,它们只是尝试在内存中发挥作用。

由于 dist 函数不计算不同数据集之间的距离,因此手动计算距离可能是最简单的,尽管包中可能有一个函数可以计算非对角线距离。

于 2013-05-28T16:52:57.380 回答