如何使用apply函数计算两个矩阵之间的距离
How to use apply function to calculate the distance between two matrices
我正在尝试计算两个矩阵之间的欧式距离。我已经实现了使用 2 个 for 循环但尝试矢量化计算以加快速度。如果距离计算正确,我使用 pdist 作为基准来验证。
多亏了这个 post、https://medium.com/@souravdey/l2-distance-matrix-vectorization-trick-26aa3247ac6c,我试图用这段代码在 r 中实现同样的事情:
dist <- sqrt(rowSums(xtest**2)+rowSums(xtrain**2)-2*xtrain %*% t(xtest))
但结果与 pdist 的结果不同。我不确定这有什么问题。
这是一些代码
创建一些数据
xtest=matrix(cbind(c(0,0),c(1,31)),2,2,byrow=TRUE)
xtrain=matrix(cbind(c(9,2),c(4,15),c(7,8),c(-22,-2)),4,2,byrow=TRUE)
使用双循环计算
mydist <- function(xtest,xtrain) {
euc.dist <- function(x1, x2) sqrt(sum((x1 - x2) ^ 2))
dist <- matrix(,nrow=nrow(xtrain),ncol=nrow(xtest))
for (i in 1:nrow(xtrain)){
for (j in 1:nrow(xtest)){
dist[i,j] <- euc.dist(xtrain[i,], xtest[j,])
}
}
return (dist)
}
> mydist(xtest,xtrain)
[,1] [,2]
[1,] 9.219544 30.08322
[2,] 15.524175 16.27882
[3,] 10.630146 23.76973
[4,] 22.090722 40.22437
结果与使用 pdist 相同
> libdists <- pdist(xtrain,xtest)
> as.matrix(libdists)
[,1] [,2]
[1,] 9.219544 30.08322
[2,] 15.524175 16.27882
[3,] 10.630146 23.76973
[4,] 22.090721 40.22437
但是如果我用矩阵乘法就错了
> mydist2 <- function(xtest,xtrain) {
+ dist <- sqrt(rowSums(xtest**2)+rowSums(xtrain**2)-2*xtrain %*% t(xtest))
+ return (dist)
+ }
> mydist2(xtest,xtrain)
[,1] [,2]
[1,] 9.219544 NaN
[2,] 34.684290 16.27882
[3,] 10.630146 NaN
[4,] 38.078866 40.22437
我也试过用mapply函数
> mydist3 <- function(xtest,xtrain) {
+ euc.dist <- function(x1, x2) sqrt(sum((x1 - x2) ^ 2))
+ dist <- mapply(euc.dist, xtest,xtrain)
+ return (dist)
+ }
> mydist3(xtest,xtrain)
[1] 9 3 7 53 2 14 8 33
我认为它是元素明智的,而不是将每一行作为一个向量来计算两个向量之间的距离。
如有任何建议,我们将不胜感激!
使用两个 apply
实例,第二个实例嵌套在第一个实例中:
d1 <- apply(xtest, 1, function(x) apply(xtrain, 1, function(y) sqrt(crossprod(x-y))))
检查 pdist
:
library(pdist)
d2 <- as.matrix(pdist(xtrain, xtest))
all.equal(d1, d2, tolerance = 1e-7)
## [1] TRUE
我正在尝试计算两个矩阵之间的欧式距离。我已经实现了使用 2 个 for 循环但尝试矢量化计算以加快速度。如果距离计算正确,我使用 pdist 作为基准来验证。
多亏了这个 post、https://medium.com/@souravdey/l2-distance-matrix-vectorization-trick-26aa3247ac6c,我试图用这段代码在 r 中实现同样的事情:
dist <- sqrt(rowSums(xtest**2)+rowSums(xtrain**2)-2*xtrain %*% t(xtest))
但结果与 pdist 的结果不同。我不确定这有什么问题。
这是一些代码
创建一些数据
xtest=matrix(cbind(c(0,0),c(1,31)),2,2,byrow=TRUE)
xtrain=matrix(cbind(c(9,2),c(4,15),c(7,8),c(-22,-2)),4,2,byrow=TRUE)
使用双循环计算
mydist <- function(xtest,xtrain) {
euc.dist <- function(x1, x2) sqrt(sum((x1 - x2) ^ 2))
dist <- matrix(,nrow=nrow(xtrain),ncol=nrow(xtest))
for (i in 1:nrow(xtrain)){
for (j in 1:nrow(xtest)){
dist[i,j] <- euc.dist(xtrain[i,], xtest[j,])
}
}
return (dist)
}
> mydist(xtest,xtrain)
[,1] [,2]
[1,] 9.219544 30.08322
[2,] 15.524175 16.27882
[3,] 10.630146 23.76973
[4,] 22.090722 40.22437
结果与使用 pdist 相同
> libdists <- pdist(xtrain,xtest)
> as.matrix(libdists)
[,1] [,2]
[1,] 9.219544 30.08322
[2,] 15.524175 16.27882
[3,] 10.630146 23.76973
[4,] 22.090721 40.22437
但是如果我用矩阵乘法就错了
> mydist2 <- function(xtest,xtrain) {
+ dist <- sqrt(rowSums(xtest**2)+rowSums(xtrain**2)-2*xtrain %*% t(xtest))
+ return (dist)
+ }
> mydist2(xtest,xtrain)
[,1] [,2]
[1,] 9.219544 NaN
[2,] 34.684290 16.27882
[3,] 10.630146 NaN
[4,] 38.078866 40.22437
我也试过用mapply函数
> mydist3 <- function(xtest,xtrain) {
+ euc.dist <- function(x1, x2) sqrt(sum((x1 - x2) ^ 2))
+ dist <- mapply(euc.dist, xtest,xtrain)
+ return (dist)
+ }
> mydist3(xtest,xtrain)
[1] 9 3 7 53 2 14 8 33
我认为它是元素明智的,而不是将每一行作为一个向量来计算两个向量之间的距离。
如有任何建议,我们将不胜感激!
使用两个 apply
实例,第二个实例嵌套在第一个实例中:
d1 <- apply(xtest, 1, function(x) apply(xtrain, 1, function(y) sqrt(crossprod(x-y))))
检查 pdist
:
library(pdist)
d2 <- as.matrix(pdist(xtrain, xtest))
all.equal(d1, d2, tolerance = 1e-7)
## [1] TRUE