【问题标题】:How to obtain complexity cosine similarity in Matlab?如何在 Matlab 中获得复杂度余弦相似度?
【发布时间】:2013-08-15 03:26:37
【问题描述】:

我已经像这样在 Matlab 中实现了余弦相似度。事实上,我有一个 50×50 的二维矩阵。要获得余弦,我应该逐行比较项目。

for j = 1:50
    x = dat(j,:);
    for i = j+1:50
        y = dat(i,:);
        c = dot(x,y);
        sim = c/(norm(x,2)*norm(y,2));
    end
end

这是正确的吗? 问题是:wath 是这种状态下的复杂度还是 O(n)?

【问题讨论】:

  • "...以逐行形式。"你的意思是按行还是按列?
  • 对不起,我的意思是逐行。两行之间
  • 是问题 a) 找到您选择的算法的复杂性(与 MATLAB 无关),b) 具有计算成对余弦相似度的有效算法(同样与 MATLAB 无关)或 c) 具有高效/快速的 MATLAB 实现?请尽量简明扼要。

标签: matlab similarity cosine-similarity


【解决方案1】:

只是关于使用向量化和矩阵运算(在 MATLAB 中进行了优化)有效实现同一事物的说明。这可以为大型矩阵节省大量时间:

dat = randn(50, 50);

OP(双换)实现

sim = zeros(size(dat));
nRow = size(dat,1);
for j = 1:nRow
    x = dat(j, :);
    for i = j+1:nRow
        y = dat(i, :);
        c = dot(x, y);
        sim(j, i) = c/(norm(x,2)*norm(y,2));
    end
end

矢量化实现:

normDat = sqrt(sum(dat.^2, 2));           % L2 norm of each row 
datNorm = bsxfun(@rdivide, dat, normDat); % normalize each row 
dotProd = datNorm*datNorm';               % dot-product vectorized (redundant!) 
sim2 = triu(dotProd, 1);                  % keep unique upper triangular part 

1000 x 1000 矩阵的比较:(MATLAB 2013a、x64、Intel Core i7 960 @ 3.20GHz)

Elapsed time is 34.103095 seconds.
Elapsed time is 0.075208 seconds.
sum(sum(sim-sim2))
ans =
    -1.224314766369880e-14

【讨论】:

  • 非常感谢您的注意。汉明距离是真的吗?以及任何相似性度量?
  • @sima412 查看pdist2 以实现为成对观察定义的不同相似性度量(包括hamming' and cosine')。
  • 好的,谢谢 gevang。但我使用到另一种类型的 hammin 距离。我想使用 1-haming。
  • 您是否可以指导我实现 (1-hammin) 的矢量化实施?
【解决方案2】:

最好以 49 结尾。也许您还应该为 sim 添加一个索引?

for j = 1:49
  x = dat(j,:);
  for i = j+1:50
      y = dat(i,:);
      c = dot(x,y);
      sim(j) = c/(norm(x,2)*norm(y,2));
  end
end

复杂度应该大概是o(n^2),不是吗? 也许你应该看看相关函数......我没有得到你想要写的确切内容,但看起来你想做类似的事情。 Matlab中内置了相关函数。

【讨论】:

  • 谢谢你 Melachtron 。我想获得复杂度余弦相似度。但另一个问题我想比较余弦相似度和汉明距离但是(1-汉明距离以获得两个向量之间的相似度)。你知道什么是复杂性汉明距离,但 1-汉明距离。和 matlab 中的 cod hamming?
  • 汉明距离见mathworks.de/de/help/stats/pdist.html——如果你想自己编程可以使用内置的Matlab命令,请看看gevang的回复
  • 你需要一个sim的双索引,即sim(j, i),否则内部i循环的每次运行都会覆盖前一个循环(因此在sim(j)中只存储最后一次调用@987654327 @)。实际上,您需要将n(n-1)/2 相似度值存储在一维或二维数组中。后者可能更方便。
猜你喜欢
  • 1970-01-01
  • 2020-08-12
  • 2017-09-27
  • 2011-03-21
  • 2011-01-01
  • 2017-02-27
  • 2013-05-24
  • 1970-01-01
相关资源
最近更新 更多