R中的平行距离矩阵

时间:2013-06-16 22:08:17

标签: r matrix parallel-processing distance spatial

目前我正在使用build in function dist来计算R中的距离矩阵。

dist(featureVector,method="manhattan")

这是目前应用程序的瓶颈,因此我们的想法是平衡这项任务(从概念上说这应该是可能的)

搜索谷歌和此论坛没有成功。

有人有想法吗?

6 个答案:

答案 0 :(得分:19)

R包amap为聚类和主成分分析提供了强大的并行化功能。在这些函数中, Dist 方法提供了您正在寻找的内容:以并行方式计算并返回距离矩阵。

Dist(x, method = "euclidean", nbproc = 8)

上面的代码用8个线程计算欧氏距离。

答案 1 :(得分:4)

这是你可以去的一条路线的结构。它不仅仅比使用dist()函数更快,而是花费更长的时间。它确实并行处理,但即使计算时间减少到零,启动函数并将变量导出到集群的时间可能比仅使用dist()

更长
library(parallel)

vec.array <- matrix(rnorm(2000 * 100), nrow = 2000, ncol = 100)

TaxiDistFun <- function(one.vec, whole.matrix) {
    diff.matrix <- t(t(whole.matrix) - one.vec)
    this.row <- apply(diff.matrix, 1, function(x) sum(abs(x)))
    return(this.row)
}

cl <- makeCluster(detectCores())
clusterExport(cl, list("vec.array", "TaxiDistFun"))

system.time(dist.array <- parRapply(cl, vec.array,
                        function(x) TaxiDistFun(x, vec.array)))

stopCluster(cl)

dim(dist.array) <- c(2000, 2000)

答案 2 :(得分:3)

您还可以使用 parallelDist 包的/* IT's just for the style, please jump to line 44 */ .container{ width: 90%; margin: auto; } .sub-container{ height:192px; overflow-y: auto; // width: 90%; } .gestion-table { background: white; //margin: auto; //width: 90%; border-collapse: collapse; } .gestion-table-head { margin-right: 15px; } .gestion-table th { color:#D5DDE5; background:#1b1e24; font-size: 18px; padding:10px; vertical-align:middle; border-right: 1px solid white; } .gestion-table tr { color:#666B85; font-size:16px; } .gestion-table tr:hover td { background:#4E5066; color:#FFFFFF; } .gestion-table tr:nth-child(odd) td { background:#EBEBEB; } .gestion-table tr:nth-child(odd):hover td { background:#4E5066; } .gestion-table td { background:#FFFFFF; padding:10px; font-size:16px; border-right: 1px solid #C1C3D1; } /* HERE STARTS THE PROBLEM */ //Switch between the two display methods on the tbody and see the result //I'm searching for scrollable tbody with max-height of 150px for example .gestion-table thead { display:table-header-group; width: 100%; } .gestion-table tbody { display:table-row-group; //display: block; overflow-y: auto; width: 100%; max-height: 150px; } 函数,该函数专为并行距离矩阵计算而构建。优点是该软件包可在Mac OS,Windows和Linux上使用,并且已经支持39种不同的距离测量(参见parDist)。

曼哈顿距离的性能比较(Sys规范:Mac OS;具有4核@ 2,5 GHz和启用超线程的Intel Core i7):

parDist

使用更大的矩阵:

library(parallelDist)
library(amap)
library(wordspace)
library(microbenchmark)

set.seed(123)
x <- matrix(rnorm(2000 * 100), nrow = 2000, ncol = 100)

microbenchmark(parDist(x, method = "manhattan"),
               Dist(x, method = "manhattan", nbproc = 8),
               dist.matrix(x, method = "manhattan"),
               times = 10)

Unit: milliseconds
                                      expr      min       lq     mean   median       uq      max neval
          parDist(x, method = "manhattan") 210.9478 214.3557 225.5894 221.3705 237.9829 247.0844    10
 Dist(x, method = "manhattan", nbproc = 8) 749.9397 755.7351 797.6349 812.6109 824.4075 844.1090    10
      dist.matrix(x, method = "manhattan") 256.0831 263.3273 279.0864 275.1882 296.3256 311.3821    10

可以在x <- matrix(rnorm(10000 * 100), nrow = 10000, ncol = 100) microbenchmark(parDist(x, method = "manhattan"), + Dist(x, method = "manhattan", nbproc = 8), + dist.matrix(x, method = "manhattan"), + times = 10) Unit: seconds expr min lq mean median uq max neval parDist(x, method = "manhattan") 6.298234 6.388501 6.737168 6.894203 6.947981 7.221661 10 Dist(x, method = "manhattan", nbproc = 8) 22.722947 24.113681 24.326157 24.477034 24.658145 25.301353 10 dist.matrix(x, method = "manhattan") 7.156861 7.505229 7.544352 7.567980 7.655624 7.800530 10 的{​​{3}}中找到进一步的效果比较。

答案 3 :(得分:2)

我是一名Windows用户正在寻找一种有效的方法来计算距离矩阵,以便在层次聚类中使用它(例如,使用“stats”包中的函数hclust)。功能 Dist在Windows中不能并行工作所以我不得不寻找不同的东西,我找到了Stefan Evert的“wordspace”包,其中包含{{ 1}}功能。 您可以尝试以下代码:

dist.matrix

正如您所见,使用X <- data.frame(replicate(1000,sample(0:1,5000,rep=TRUE))) system.time(d <- dist(X, method = "manhattan")) system.time(d2 <- as.dist( dist.matrix(as.matrix(X), method="manhattan") ))

计算具有1000个二进制特征和5000个实例的数据帧的距离矩阵要快得多

这些是我的笔记本电脑(i7-6500U)中的结果:

dist.matrix

这解决了我的问题。在这里你可以检查我发现它的原始线程: http://r.789695.n4.nabble.com/Efficient-distance-calculation-on-big-matrix-td4633598.html

它没有并行解决,但在很多场合都足够了。

答案 4 :(得分:1)

我也在使用一些大的距离矩阵并尝试加速计算。 Benson上面说的可能是正确的,当他说&#34;启动函数并将变量导出到集群的时间可能比使用&#34;更长。

但是,我认为这适用于小到中等大小的距离矩阵。请使用包含统计数据包含10个处理器 amap 的函数Distdist以及rdist查看示例来自字段的包,它调用Fortran函数。第一个示例创建一个400 x 400距离矩阵。第二个创建一个3103 x 3103距离矩阵。

require(sp)
require(fields)
require(amap)
data(meuse.grid)
meuse.gridA <- meuse.grid[1:400, 1:2]
meuse.gridB <- meuse.grid[, 1:2]

# small distance matrix
a <- Sys.time()
invisible(dist(meuse.gridA, diag = TRUE, upper = TRUE))
Sys.time() - a
Time difference of 0.002138376 secs
a <- Sys.time()
invisible(Dist(meuse.gridA, nbproc = 10, diag = TRUE, upper = TRUE))
Sys.time() - a
Time difference of 0.005409241 secs
a <- Sys.time()
invisible(rdist(meuse.gridA))
Sys.time() - a
Time difference of 0.02312016 secs

# large distance matrix
a <- Sys.time()
invisible(dist(meuse.gridB, diag = TRUE, upper = TRUE))
Sys.time() - a
Time difference of 0.09845328 secs
a <- Sys.time()
invisible(Dist(meuse.gridB, nbproc = 10, diag = TRUE, upper = TRUE))
Sys.time() - a
Time difference of 0.05900002 secs
a <- Sys.time()
invisible(rdist(meuse.gridB))
Sys.time() - a
Time difference of 0.8928168 secs

注意当距离矩阵很大(3103 x 3103)时,使用Dist计算时间从0.09845328秒减少到0.05900002秒与dist相比。因此,如果您有多个可用的处理器,我建议您使用 amap 包中的函数Dist

答案 5 :(得分:0)

我发现parallelDist比dist快几个数量级,并且在我的Mac上使用Microsoft R Open 3.4.0在这个过程中嚼掉了更少的虚拟内存。但是有一个警告 - 我在R 3.3.3上没有运气编译。它没有列出R作为依赖的版本,但我怀疑它是。