我坚持在MATLAB / Octave中对这个棘手的循环进行矢量化:
[nr, nc] = size(R);
P = rand(nr, K);
Q = rand(K, nc);
for i = 1:nr
for j = 1:nc
if R(i,j) > 0
eij = R(i,j) - P(i,:)*Q(:,j);
for k = 1:K
P(i,k) = P(i,k) + alpha * (2 * eij * Q(k,j) - beta * P(i,k));
Q(k,j) = Q(k,j) + alpha * (2 * eij * P(i,k) - beta * Q(k,j));
end
end
end
end
代码尝试将R分解为P和Q,并使用更新规则逼近最近的P和Q.例如,设R = [3 4 0 1 1; 0 1 0 4 4; 5 4 3 1 0; 0 0 5 4 3; 5 3 0 2 1],K = 2,α= 0.01,β= 0.015。在我的实际情况中,我将使用一个巨大的稀疏矩阵R(这就是我需要矢量化的原因),并且K仍然很小(小于10)。整个脚本的目标是基于非零元素为R中的每0个元素生成预测值。我从here获得了这段代码,最初是用Python编写的。
答案 0 :(得分:1)
这看起来像是不是所有代码都可以向量化的情况之一。不过,你可以让它比现在好一些。
[nr, nc] = size(R);
P = rand(nr, K);
Q = rand(K, nc);
for i = 1:nr
for j = 1:nc
if R(i,j) > 0
eij = R(i,j) - P(i,:)*Q(:,j);
P(i,:) = P(i,:) + alpha * (2 * eij * Q(:,j)' - beta * P(i,:));
Q(:,j) = Q(:,j) + alpha * (2 * eij * P(i,:)' - beta * Q(:,j));
end
end
end
答案 1 :(得分:1)
由于P
和Q
上的操作本质上是串行的(迭代更新),我认为你不能做得更好。您可以将if
保存在循环中:
[nr, nc] - size(R);
P = rand(nr, K);
Q = rand(K, nc);
[nzi nzj] = find( R > 0 );
for ii=1:numel(nzi)
i = nzi(ii);
j = nzj(ii);
eij = R(i,j) - P(i,:)*Q(:,j);
P(i,:) = P(i,:) + alpha * (2 * eij * Q(:,j)' - beta * P(i,:));
Q(:,j) = Q(:,j) + alpha * (2 * eij * P(i,:)' - beta * Q(:,j));
end