JSD矩阵是基于Jensen-Shannon散度的分布的相似性矩阵.给定矩阵m哪些行呈现分布,我们希望找到每个分布之间的JSD距离.得到的JSD矩阵是一个方形矩阵,其维数为nrow(m)x nrow(m).这是三角矩阵,其中每个元素包含m行中两行之间的JSD值.
JSD可以通过以下R函数计算:
JSD<- function(x,y) sqrt(0.5 * (sum(x*log(x/((x+y)/2))) + sum(y*log(y/((x+y)/2)))))
Run Code Online (Sandbox Code Playgroud)
其中x,y是矩阵m中的行.
我在R中尝试了不同的JSD矩阵计算算法,以找出最快的算法.令我惊讶的是,具有两个嵌套循环的算法比不同的矢量化版本(并行化或非并行化)执行得更快.我对结果不满意.你能找到比我游戏更好的解决方案吗?
library(parallel)
library(plyr)
library(doParallel)
library(foreach)
nodes <- detectCores()
cl <- makeCluster(4)
registerDoParallel(cl)
m <- runif(24000, min = 0, max = 1)
m <- matrix(m, 24, 1000)
prob_dist <- function(x) t(apply(x, 1, prop.table))
JSD<- function(x,y) sqrt(0.5 * (sum(x*log(x/((x+y)/2))) + sum(y*log(y/((x+y)/2)))))
m <- t(prob_dist(m))
m[m==0] <- 0.000001
Run Code Online (Sandbox Code Playgroud)
具有两个嵌套循环的算法:
dist.JSD_2 <- function(inMatrix) {
matrixColSize <- ncol(inMatrix)
resultsMatrix <- matrix(0, matrixColSize, matrixColSize)
for(i in 2:matrixColSize) {
for(j in 1:(i-1)) {
resultsMatrix[i,j]=JSD(inMatrix[,i], …Run Code Online (Sandbox Code Playgroud) 我有一个有n行观察的矩阵.观察是特征的频率分布.我想将频率分布转换为概率分布,其中每行的总和为1.因此,矩阵中的每个元素应除以元素行的总和.
我编写了以下R函数来完成工作,但是对于大型矩阵来说它非常慢:
prob_dist <- function(x) {
row_prob_dist <- function(row) {
return (t(lapply(row, function(x,y=sum(row)) x/y)))
}
for (i in 1:nrow(x)) {
if (i==1) p_dist <- row_prob_dist(x[i,])
else p_dist <- rbind(p_dist, row_prob_dist(x[i,]))
}
return(p_dist)
}
B = matrix(c(2, 4, 3, 1, 5, 7), nrow=3, ncol=2)
B
[,1] [,2]
[1,] 2 1
[2,] 4 5
[3,] 3 7
prob_dist(B)
[,1] [,2]
[1,] 0.6666667 0.3333333
[2,] 0.4444444 0.5555556
[3,] 0.3 0.7
Run Code Online (Sandbox Code Playgroud)
你能建议R功能完成这项工作和/或告诉我如何优化我的功能以更快地执行?