加快 R 中逐点差异之和的计算
Speed up of the calculation of the sum the point-wise difference in R
假设我有两个数据集。第一个是:
t1<-sample(1:10,10,replace = T)
t2<-sample(1:10,10,replace = T)
t3<-sample(1:10,10,replace = T)
t4<-sample(11:20,10,replace = T)
t5<-sample(11:20,10,replace = T)
xtrain<-rbind(t1,t2,t3,t4,t5)
xtrain
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
t1 7 3 9 10 4 9 2 1 6 9
t2 5 1 1 6 5 3 10 2 6 3
t3 8 6 9 7 9 2 3 5 1 8
t4 16 18 14 17 19 20 15 15 20 19
t5 13 14 18 13 11 19 13 17 16 14
第二个是:
t6<-sample(1:10,10,replace = T)
t7<-sample(11:20,10,replace = T)
xtest<-rbind(t6,t7)
xtest
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
t6 1 5 8 2 10 2 3 4 8 5
t7 14 18 15 12 17 20 17 13 16 17
我喜欢做的是计算xtest
的每一行和xtrain
的每一行之间的距离之和。例如:
sum((7-1)^2+(3-5)^2+(9-8)^2+.....(9-5)^2)
sum((5-1)^2+(1-5)^2+(1-8)^2+.....(4-5)^2)
...
sum((14-13)^2+(18-14)^2+(15-18)^2+.....(17-14)^2)
我目前有的是使用两个 for 循环(见下文),我认为这不能处理大数据集:
sumPD<-function(vector1,vector2){
sumPD1<-sum((vector1-vector2)^2)
return(sumPD1)
}
loc<-matrix(NA,nrow=dim(xtrain)[1],ncol=dim(xtest)[1])
for(j in 1:dim(xtest)[1]){
for(i in 1:dim(xtrain)[1]){
loc[i,j]<-sumPD(xtrain[i,],xtest[j,])
}
}
我想就如何修改代码以使其高效提出建议。先感谢您!希望大家好好讨论!
一个选项是outer
f1 <- Vectorize(function(i, j) sumPD(xtrain[i,], xtest[j,]))
loc2 <- outer(seq_len(nrow(xtrain)), seq_len(nrow(xtest)), f1)
identical(loc, loc2)
#[1] TRUE
rdist
包具有快速计算这些成对距离的函数:
rdist::cdist(xtrain, xtest)^2
输出:
[,1] [,2]
[1,] 65 1029
[2,] 94 1324
[3,] 165 1103
[4,] 1189 213
[5,] 1271 191
这里有两个简单的方法。
使用dist
- 将计算比需要更多的距离:
dists <- as.matrix(dist(rbind(xtrain, xtest))^2)
dists <- dists[rownames(xtrain), rownames(xtest)]
dists
t6 t7
t1 140 1179
t2 134 693
t3 119 974
t4 1028 91
t5 1085 44
使用适用于 X 矩阵和 y 向量的简单自定义函数:
euclid <- function(X,y) colSums((X-y)^2)
dists <- mapply(euclid, list(t(xtrain)), split(xtest, row(xtest)))
dists
[,1] [,2]
t1 140 1179
t2 134 693
t3 119 974
t4 1028 91
t5 1085 44
您可以转置您的矩阵,使用向量差分和单个循环:
ftrain <- t(xtrain)
ftest <- t(xtest)
sapply(1:(dim(ftest)[2]),function(i){
colSums((ftrain - ftest[,i])^2)
})
[,1] [,2]
t1 103 1182
t2 125 1262
t3 130 1121
t4 1478 159
t5 1329 142
colSums
效率很高,但如果你想要更快的速度,请看一下
假设我有两个数据集。第一个是:
t1<-sample(1:10,10,replace = T)
t2<-sample(1:10,10,replace = T)
t3<-sample(1:10,10,replace = T)
t4<-sample(11:20,10,replace = T)
t5<-sample(11:20,10,replace = T)
xtrain<-rbind(t1,t2,t3,t4,t5)
xtrain
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
t1 7 3 9 10 4 9 2 1 6 9
t2 5 1 1 6 5 3 10 2 6 3
t3 8 6 9 7 9 2 3 5 1 8
t4 16 18 14 17 19 20 15 15 20 19
t5 13 14 18 13 11 19 13 17 16 14
第二个是:
t6<-sample(1:10,10,replace = T)
t7<-sample(11:20,10,replace = T)
xtest<-rbind(t6,t7)
xtest
[,1] [,2] [,3] [,4] [,5] [,6] [,7] [,8] [,9] [,10]
t6 1 5 8 2 10 2 3 4 8 5
t7 14 18 15 12 17 20 17 13 16 17
我喜欢做的是计算xtest
的每一行和xtrain
的每一行之间的距离之和。例如:
sum((7-1)^2+(3-5)^2+(9-8)^2+.....(9-5)^2)
sum((5-1)^2+(1-5)^2+(1-8)^2+.....(4-5)^2)
...
sum((14-13)^2+(18-14)^2+(15-18)^2+.....(17-14)^2)
我目前有的是使用两个 for 循环(见下文),我认为这不能处理大数据集:
sumPD<-function(vector1,vector2){
sumPD1<-sum((vector1-vector2)^2)
return(sumPD1)
}
loc<-matrix(NA,nrow=dim(xtrain)[1],ncol=dim(xtest)[1])
for(j in 1:dim(xtest)[1]){
for(i in 1:dim(xtrain)[1]){
loc[i,j]<-sumPD(xtrain[i,],xtest[j,])
}
}
我想就如何修改代码以使其高效提出建议。先感谢您!希望大家好好讨论!
一个选项是outer
f1 <- Vectorize(function(i, j) sumPD(xtrain[i,], xtest[j,]))
loc2 <- outer(seq_len(nrow(xtrain)), seq_len(nrow(xtest)), f1)
identical(loc, loc2)
#[1] TRUE
rdist
包具有快速计算这些成对距离的函数:
rdist::cdist(xtrain, xtest)^2
输出:
[,1] [,2]
[1,] 65 1029
[2,] 94 1324
[3,] 165 1103
[4,] 1189 213
[5,] 1271 191
这里有两个简单的方法。
使用dist
- 将计算比需要更多的距离:
dists <- as.matrix(dist(rbind(xtrain, xtest))^2)
dists <- dists[rownames(xtrain), rownames(xtest)]
dists
t6 t7
t1 140 1179
t2 134 693
t3 119 974
t4 1028 91
t5 1085 44
使用适用于 X 矩阵和 y 向量的简单自定义函数:
euclid <- function(X,y) colSums((X-y)^2)
dists <- mapply(euclid, list(t(xtrain)), split(xtest, row(xtest)))
dists
[,1] [,2]
t1 140 1179
t2 134 693
t3 119 974
t4 1028 91
t5 1085 44
您可以转置您的矩阵,使用向量差分和单个循环:
ftrain <- t(xtrain)
ftest <- t(xtest)
sapply(1:(dim(ftest)[2]),function(i){
colSums((ftrain - ftest[,i])^2)
})
[,1] [,2]
t1 103 1182
t2 125 1262
t3 130 1121
t4 1478 159
t5 1329 142
colSums
效率很高,但如果你想要更快的速度,请看一下