减少NbClust的内存使用量

时间:2019-08-27 23:30:43

标签: r memory cluster-analysis matrix-multiplication

我需要一些有关NbClust函数大量使用内存的帮助。 在我的数据上,内存膨胀到56GB,此时R发生致命错误,崩溃了。使用debug(),我能够将错误跟踪到以下几行:

            if (any(indice == 23) || (indice == 32)) {
                res[nc - min_nc + 1, 23] <- Index.sPlussMoins(cl1 = cl1, 
                    md = md)$gamma

对Index.sPlussMoins的调试显示,崩溃发生在for循环期间。它崩溃的迭代次数各不相同,并且在循环期间内存使用量在41到57Gb之间(我总共有64Gb):

    for (k in 1:nwithin1) {
      s.plus <- s.plus + (colSums(outer(between.dist1, 
                                        within.dist1[k], ">")))
      s.moins <- s.moins + (colSums(outer(between.dist1, 
                                          within.dist1[k], "<")))
      print(s.moins)
    }

我猜测内存使用量来自outer()函数。 我可以修改NbClust使其具有更高的内存效率吗(也许使用bigmemory包)? 至少,最好让R以“无法分配大小向量...”退出函数而不是崩溃。这样一来,我就会知道处理导致崩溃的矩阵需要多少内存。

编辑:我创建了一个最小的示例,该示例的矩阵近似于我正在使用的矩阵的大小,尽管当调用hclust函数时,它崩溃于另一个点:

set.seed(123)

cluster_means = sample(1:25, 10)
mlist = list()
for(cm in cluster_means){
  name = as.character(cm)
  m = data.frame(matrix(rnorm(60000*60,mean=cm,sd=runif(1, 0.5, 3.5)), 60000, 60))
  mlist[[name]] = m
}

test_data = do.call(cbind, cbind(mlist))

library(NbClust)
debug(fun = "NbClust")
nbc = NbClust(data = test_data, diss = NULL, distance = "euclidean", min.nc = 2, max.nc = 30, 
              method = "ward.D2", index = "alllong", alphaBeale = 0.1)
debug: hc <- hclust(md, method = "ward.D2")

它似乎在用尽可用内存之前就崩溃了(根据我的系统监视器,当崩​​溃总数达到64时,正在使用34Gb。

那么,在没有对可管理大小的矩阵进行二次采样的情况下,有什么方法可以做到这一点?如果这样做了,我如何知道给定大小的矩阵需要多少内存?我本以为我的64Gb足够了。

编辑: 我尝试将NbClust更改为使用fastcluster而不是统计信息版本。它没有崩溃,但是退出并出现内存错误:

Browse[2]> 
exiting from: fastcluster::hclust(md, method = "ward.D2")
Error: cannot allocate vector of size 9.3 Gb

2 个答案:

答案 0 :(得分:1)

如果查看Nbclust的源代码,您会发现它几乎已针对速度或内存效率进行了优化。

您要报告的崩溃甚至不在集群期间-而是在评估之后,尤其是在“ Gamma,Gplus和Tau”索引代码中。 禁用这些索引,您可能会走得更远,但很可能在另一个索引中再次遇到相同的问题。也许您只能选择要运行的几个索引,特别是这样的索引,以至于 不需要很多内存?

答案 1 :(得分:0)

我分叉了NbClust并进行了一些更改,这些更改似乎使它运行了更长的时间,而不会因使用更大的矩阵而崩溃。我更改了一些功能以使用Rfastpropagatefastcluster。但是仍然存在问题。

我还没有运行我的所有数据,仅使用gap对虚拟数据进行了一些测试,因此仍然有时间使它失败。但是任何建议/批评都将受到欢迎。 我的NbCluster(正在进行中)分叉: https://github.com/jbhanks/NbClust