R (速度挑战)有没有更快的方法根据通用汉明距离计算距离矩阵?

R (速度挑战)有没有更快的方法根据通用汉明距离计算距离矩阵?,r,algorithm,performance,matrix,hamming-distance,R,Algorithm,Performance,Matrix,Hamming Distance,我正在寻找一种更有效的方法来获得距离矩阵 背景 我知道包e1071中有一个函数hamming.distance()来计算距离矩阵,但我怀疑当涉及一个包含许多行的大型矩阵时,它可能会非常慢,因为它为计算应用了嵌套的循环 到目前为止,我在下面的代码中找到了一种更快的方法(请参见methodB)。然而,它仅适用于二进制域中的,即{0,1}^n。但是,当遇到由两个以上元素组成的域时,即,{0,1,2,…,K-1}^n,它不可用。从这个意义上说,methodB不是通用的汉明距离 目标 library(e1

我正在寻找一种更有效的方法来获得距离矩阵

背景

我知道包
e1071
中有一个函数
hamming.distance()
来计算距离矩阵,但我怀疑当涉及一个包含许多行的大型矩阵时,它可能会非常慢,因为它为计算应用了嵌套的
循环

到目前为止,我在下面的代码中找到了一种更快的方法(请参见
methodB
)。然而,它仅适用于二进制域中的,即
{0,1}^n
。但是,当遇到由两个以上元素组成的域时,即,
{0,1,2,…,K-1}^n
,它不可用。从这个意义上说,
methodB
不是通用的汉明距离

目标

library(e1071)
# vector length, i.e., number of matrix
n <- 7
# number of elements to consist of domain {0,1,...,k-1}^n
k <- 2
# matrix for computing hamming distances by rows
m <- as.matrix(do.call(expand.grid,replicate(n,list(0:k-1))))

# applying `hamming.distance()` from package "e1071", which is generic so it is available for any positive integer `k`
methodA <- function(M) hamming.distance(M)
# my customized method from base R function `dist()`, which is not available for cases `k >= 2`
methodB <- function(M) as.matrix(round(dist(M,upper = T,diag = T)**2))

我的目标是找到一种具有以下特点的方法:

  • 仅由基本R的函数组成(不使用
    Rcpp
    重写函数以加速)
  • 对于特殊情况
    k=2
  • 可以推广到任何正整数
    k
  • 超越来自软件包的
    hamming.distance()
    的速度
    e1071
我的代码

library(e1071)
# vector length, i.e., number of matrix
n <- 7
# number of elements to consist of domain {0,1,...,k-1}^n
k <- 2
# matrix for computing hamming distances by rows
m <- as.matrix(do.call(expand.grid,replicate(n,list(0:k-1))))

# applying `hamming.distance()` from package "e1071", which is generic so it is available for any positive integer `k`
methodA <- function(M) hamming.distance(M)
# my customized method from base R function `dist()`, which is not available for cases `k >= 2`
methodB <- function(M) as.matrix(round(dist(M,upper = T,diag = T)**2))


提前感谢

methodM您是否尝试过使用
Rcpp
?我有一个非常相似的问题!请看这里的答案:

我发现这个博客有四篇关于计算汉明矩阵的文章。我不想因为它而声名鹊起,但也许可以看看它。
methodM <- function(x) {
  xt <- t(x)
  sapply(1:nrow(x), function(y) colSums(xt != xt[, y]))
}
microbenchmark::microbenchmark(
  methodB(m), methodM(m),
  unit = "relative", check = "equivalent", times = 50
)
# Unit: relative
#       expr  min       lq     mean   median       uq      max neval cld
# methodB(m) 1.00 1.000000 1.000000 1.000000 1.000000 1.000000    50  a 
# methodM(m) 1.25 1.224827 1.359573 1.219507 1.292463 4.550159    50   b


hamming谢谢你的回答!是的,您的方法很快,可以扩展到
k>2
的情况。对于特殊情况
k=2
,您是否知道它比我的
methodB()更快?@thomasscoding它不会更快,可能是因为它没有使用低级别的优化函数
dist
。此外,这还可以计算所有距离,理想情况下,我们希望使用更好的算法,只计算上(下)三角形部分的值。是的,我明白了,也许我们已经有了使用base R的速度限制。这可能会引起您的兴趣:@chinsoon12感谢您提供的信息,我将查看itThanks,但我想使用base R(而不是
Rcpp
),正如我在博文中所说的,谢谢你的贡献。向上投票!
hamming <- function(X) {
  D <- (1 - X) %*% t(X)
  D + t(D)
}

> microbenchmark::microbenchmark(
+   methodB(m),
+   hamming(m),
+   unit = "relative",
+   times = 50
+ )
Unit: relative
       expr    min       lq     mean   median       uq      max neval
 methodB(m) 1.0000 1.000000 1.000000 1.000000 1.000000 1.000000    50
 hamming(m) 1.2502 1.299844 1.436486 1.301461 1.302033 4.607748    50