matlab中的余弦相似度内置函数

cosine similarity built-in function in matlab

我想在 matlab 中计算矩阵不同行之间的余弦相似度。我在matlab中写了下面的代码:

for i = 1:n_row
    for j = i:n_row
        S2(i,j) = dot(S1(i,:), S1(j,:)) / (norm_r(i) * norm_r(j));
        S2(j,i) = S2(i,j);

矩阵S1为11000*11000,代码执行非常耗时。所以,我想知道matlab中有没有什么函数可以比上面的代码更快地计算矩阵行之间的余弦相似度?

您的代码循环遍历所有行,并且对于每一行循环遍历(大约)一半的行,计算每个唯一行组合的点积:

n_row = size(S1,1);
norm_r = sqrt(sum(abs(S1).^2,2)); % same as norm(S1,2,'rows')
S2 = zeros(n_row,n_row);
for i = 1:n_row
  for j = i:n_row
    S2(i,j) = dot(S1(i,:), S1(j,:)) / (norm_r(i) * norm_r(j));
    S2(j,i) = S2(i,j);
  end
end

(我冒昧地完成了你的代码,所以它实际运行了。注意在循环之前初始化 S2,这样可以节省很多时间!)

如果您注意到点积是行向量与列向量的矩阵乘积,您会发现上面的内容在没有归一化步骤的情况下与

相同
S2 = S1 * S1.';

这比显式循环运行得快得多,即使它(也许?)无法使用对称性。规范化只是将每一行除以 norm_r,将每一列除以 norm_r。在这里,我将两个向量相乘以生成一个方阵以进行归一化:

S2 = (S1 * S1.') ./ (norm_r * norm_r.');

通过计算与pdist的相似度的简短版本:

S2 = squareform(1-pdist(S1,'cosine')) + eye(size(S1,1));

解释:

pdist(S1,'cosine')计算S1中所有行组合之间的余弦距离。因此所有组合之间的相似度为 1 - pdist(S1,'cosine') .

我们可以将其转换为方阵,其中元素 (i,j) 对应于行 ijsquareform(1-pdist(S1,'cosine')) 之间的相似度。

最后我们必须将主对角线设置为 1,因为一行与其自身的相似度显然是 1,但 pdist 没有明确计算。