没有嵌套循环的余弦相似度计算

时间:2016-02-11 14:49:55

标签: r

我试图通过使用余弦相似性来编写相似度矩阵,并且我使用了嵌套循环。我知道嵌套循环在R中并不总是惯用的,这个实现需要花费很多时间来执行。

我想知道如何将此代码转换为没有嵌套循环的代码。

 cosine.sim <- function(data) 
{
        data <- t(data)
        cos.sim <- matrix (data = 1, nrow = ncol(data), ncol = ncol(data))
        for(i in 1:(ncol(data)-1))
        {
                for(j in (i+1):ncol(data))
                {
                        A <- sqrt ( sum (data[,i] ^2) )
                        B <- sqrt ( sum (data[,j] ^2) )
                        C <- sum ( data[,i] * data[,j] ) 
                        cos.sim [i,j] <- C / (A * B)
                        cos.sim [j,i] <- C / (A * B)
                }
        }
        return (cos.sim)
}

1 个答案:

答案 0 :(得分:4)

使用低级交叉乘积函数应该比在R中做同样的速度快几个数量级。

示例数据

> set.seed(1)
> (data<-matrix(runif(30),5,6))
          [,1]       [,2]      [,3]      [,4]      [,5]       [,6]
[1,] 0.2655087 0.89838968 0.2059746 0.4976992 0.9347052 0.38611409
[2,] 0.3721239 0.94467527 0.1765568 0.7176185 0.2121425 0.01339033
[3,] 0.5728534 0.66079779 0.6870228 0.9919061 0.6516738 0.38238796
[4,] 0.9082078 0.62911404 0.3841037 0.3800352 0.1255551 0.86969085
[5,] 0.2016819 0.06178627 0.7698414 0.7774452 0.2672207 0.34034900

以下是等效的

 > tcrossprod(data/sqrt(rowSums(data^2)))
          [,1]      [,2]      [,3]      [,4]      [,5]
[1,] 1.0000000 0.8193235 0.8644710 0.6829105 0.5854560
[2,] 0.8193235 1.0000000 0.8523731 0.6810237 0.5835957
[3,] 0.8644710 0.8523731 1.0000000 0.7884536 0.8815997
[4,] 0.6829105 0.6810237 0.7884536 1.0000000 0.6324778
[5,] 0.5854560 0.5835957 0.8815997 0.6324778 1.0000000

但可能比你的功能快得多

> cosine.sim(data)
          [,1]      [,2]      [,3]      [,4]      [,5]
[1,] 1.0000000 0.8193235 0.8644710 0.6829105 0.5854560
[2,] 0.8193235 1.0000000 0.8523731 0.6810237 0.5835957
[3,] 0.8644710 0.8523731 1.0000000 0.7884536 0.8815997
[4,] 0.6829105 0.6810237 0.7884536 1.0000000 0.6324778
[5,] 0.5854560 0.5835957 0.8815997 0.6324778 1.0000000