2017-08-22 61 views
1

问题描述R个时间系列距离计算

期间运行内存我有45000短的时间序列(长度为9),并希望计算用于聚类分析的距离。我意识到这将导致(大小为三角形的)45000x45000大小的矩阵,这是一个具有超过20亿条目的矩阵。不出所料,我得到:

> proxy::dist(ctab2, method="euclidean") 
Error: cannot allocate vector of size 7.6 Gb 

我该怎么办?

理念

  • 增加可用/寻址存储器不知何故?但是,这些7.6G可能超出了一些无法扩展的硬限制?无论如何,该系统具有16GB内存和相同数量的交换。以“Gb”来说,R似乎意味着技嘉,而不是千兆,所以7.6Gb让我们已经危险地接近硬性极限。
  • 也许不同的距离计算方法,而不是欧几里德,比如说DTW,可能会更有效率的内存?但是,如下所述,内存限制似乎是结果矩阵,而不是计算时所需的内存。
  • 将数据集拆分为N个块,然后计算N^2个部分中的矩阵(实际上只有与下部三角形相关的那些部分),以后可以重新组合? (这可能看起来类似于提出的类似问题的解决方案。)但这似乎是一个相当混乱的解决方案。此外,无论如何,我将最终需要45K x 45K矩阵。但是,这似乎达到了极限。产生45K X 45K随机矩阵时,系统也给出了内存分配错误:

    > N=45000; memorytestmatrix <- matrix(rnorm(N*N,mean=0,sd=1), N, N) Error: cannot allocate vector of size 15.1 Gb

    30K X 30K基质是可能的而不会出现问题,R给出了所得大小为

    > print(object.size(memorytestmatrix), units="auto") 6.7 Gb

    1 Gb更多,看起来一切都会好起来的。可悲的是,我没有任何可以删除的大型对象来腾出空间。此外,讽刺的是,

    > system('free -m') Warning message: In system("free -m") : system call failed: Cannot allocate memory

    我不得不承认,我真的不知道为什么[R拒绝分配7.6 GB;该系统肯定有更多的记忆,尽管没有更多。 ps aux将R进程显示为单个最大内存用户。即使有更多的内存可用,内存R可以处理多少内存也有问题?

相关问题

  • 解答作为R运行内存,像this one,其他问题建议使用更多的内存计算的有效方法。
  • This very helpful answer建议删除其他大对象以腾出空间进行内存密集型操作。
  • Here,建议分块数据集和计算距离的想法。

软件&版本

[R版本3.4.1是。系统内核是Linux 4.7.6,x86_64(即64位)。

> version 
      _       
platform  x86_64-pc-linux-gnu   
arch   x86_64      
os    linux-gnu     
system   x86_64, linux-gnu   
status          
major   3       
minor   4.1       
year   2017       
month   06       
day   30       
svn rev  72865      
language  R       
version.string R version 3.4.1 (2017-06-30) 
nickname  Single Candle 

编辑(8月27日):一些更多信息

  • 更新Linux内核4.11.9没有影响。
  • 大内存包也可能用完内存。它使用/dev/shm/中的共享内存,其中系统默认(但取决于配置)允许RAM的一半大小。您可以在运行时增加此(例如)mount -o remount,size=12Gb /dev/shm,但这可能仍然不允许使用12Gb。 (我不知道为什么,也许内存管理配置不一致)。另外,you may end up crashing your system if you are not careful
  • R显然实际上允许访问完整的RAM,并可以创建达到该大小的对象。它似乎只对特定功能(例如dist)失败。我会加上这个答案作为答案,但是我的结论有点基于猜测,所以我不知道这是对的。
+0

您是否尝试过使用R x64? – Kanak

+0

@Kanak是的,我在x86_64系统上。 'version'给出'... arch x86_64 ...' – 0range

+0

我还检查了R:'> .Machine $ sizeof中的指针大小。指针“赋予'[1] 8',这反过来意味着它确实是64位。 (指针大小将在32位上为4。) – 0range

回答

0

R显然实际上允许访问完整的RAM。这工作完全正常:

N=45000; memorytestmatrix <- matrix(nrow=N, ncol=N) 

这是我在原来的问题描述尝试过同样的事情,但与NA的,而不是rnorm随机变元的矩阵。将矩阵中的一个值重新分配为float(memorytestmatrix[1,1]<-0.5)仍然有效,并将该矩阵重新映射为浮点矩阵。

因此,我想,你可以有一个这样大小的矩阵,但是你不能像dist函数那样做。一个可能的解释是该函数使用该尺寸的多个对象进行操作,以便加速计算。但是,如果您按照元素的方式计算距离并更改值,则可以使用。

library(mefa)  # for the vec2dist function 

euclidian <- function(series1, series2) { 
    return((sum((series1 - series2)^2))^.5) 
} 

mx = nrow(ctab2) 
distMatrixE <- vec2dist(0.0, size=mx) 
for (coli in 1:(mx-1)) { 
    for (rowi in (coli+1):mx) { 
     # Element indices in dist objects count the rows down column by column from left to righ in lower triangular matrices without the main diagonal. 
     # From row and column indices, the element index for the dist object is computed like so: 
     element <- (mx^2-mx)/2 - ((mx-coli+1)^2 - (mx-coli+1))/2 + rowi - coli 
     # ... and now, we replace the distances in place 
     distMatrixE[element] <- euclidian(ctab2[rowi,], ctab2[coli,]) 
    } 
} 

(注意,在dist对象寻址是有点棘手,因为它们不是矩阵但尺寸(N 2 - N)/ 2重铸作为大小的下三角矩阵的N×1维向量N。如果我们按照正确的顺序遍历行和列,它也可以用一个计数器变量来完成,但我想明确地计算元素索引更清晰。)

另请注意,它可能可以通过一次计算多个值来利用sapply来提高速度。

0

存在很好的算法,在内存中不需要全距离矩阵

例如,SLINK和DBSCAN以及OPTICS。