使用R中的矩阵乘法计算行余弦相似度
Calculating the row wise cosine similarity using matrix multiplication in R
在下面的示例中,我使用自定义函数和 for 循环计算了矩阵中数据的行余弦相似度。我想要的输出是一个对称矩阵。
我想在没有 for 循环的情况下使用矩阵乘法(线性代数)来实现此计算,因为我需要处理的实际输入矩阵要大得多,而且循环会太慢。
x = c(0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1)
x = matrix(x, nrow = 3, byrow = TRUE)
cosine_similarity = function(a, b){
y = crossprod(a, b) / sqrt(crossprod(a) * crossprod(b))
return(y)
}
N_row = dim(x)[1]
similarity_matrix = matrix(0, nrow = N_row, ncol = N_row)
for (i in 1:(N_row-1)) {
for (j in (i + 1):N_row) {
similarity_matrix[i,j] = cosine_similarity(x[i,], x[j,])
}
}
similarity_matrix = similarity_matrix + t(similarity_matrix)
我们可以使用 outer
来加快速度
outer(seq_len(nrow(x)), seq_len(nrow(x)),
FUN = Vectorize(function(i, j) cosine_similarity(x[i,], x[j, ])))
-输出
# [,1] [,2] [,3]
#[1,] 1.0000000 0.5000000 0.4082483
#[2,] 0.5000000 1.0000000 0.4082483
#[3,] 0.4082483 0.4082483 1.0000000
或者另一个选项是 combn
out <- diag(nrow(x)) * 0
out[upper.tri(out)] <- combn(seq_len(nrow(x)), 2,
FUN = function(i) c(cosine_similarity(x[i[1], ], x[i[2],])))
out <- out + t(out)
diag(out) <- 1
在下面的示例中,我使用自定义函数和 for 循环计算了矩阵中数据的行余弦相似度。我想要的输出是一个对称矩阵。
我想在没有 for 循环的情况下使用矩阵乘法(线性代数)来实现此计算,因为我需要处理的实际输入矩阵要大得多,而且循环会太慢。
x = c(0, 1, 1, 0, 0, 1, 0, 1, 1, 0, 1, 1)
x = matrix(x, nrow = 3, byrow = TRUE)
cosine_similarity = function(a, b){
y = crossprod(a, b) / sqrt(crossprod(a) * crossprod(b))
return(y)
}
N_row = dim(x)[1]
similarity_matrix = matrix(0, nrow = N_row, ncol = N_row)
for (i in 1:(N_row-1)) {
for (j in (i + 1):N_row) {
similarity_matrix[i,j] = cosine_similarity(x[i,], x[j,])
}
}
similarity_matrix = similarity_matrix + t(similarity_matrix)
我们可以使用 outer
来加快速度
outer(seq_len(nrow(x)), seq_len(nrow(x)),
FUN = Vectorize(function(i, j) cosine_similarity(x[i,], x[j, ])))
-输出
# [,1] [,2] [,3]
#[1,] 1.0000000 0.5000000 0.4082483
#[2,] 0.5000000 1.0000000 0.4082483
#[3,] 0.4082483 0.4082483 1.0000000
或者另一个选项是 combn
out <- diag(nrow(x)) * 0
out[upper.tri(out)] <- combn(seq_len(nrow(x)), 2,
FUN = function(i) c(cosine_similarity(x[i[1], ], x[i[2],])))
out <- out + t(out)
diag(out) <- 1