我已经在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
这是正确的吗?问题是:在这种状态下,O(n)的复杂性是多少?
只是关于使用矢量化和矩阵运算(在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
最好以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中有内置的相关函数。