在矩阵中迭代避免MATLAB中的循环

时间:2016-02-11 00:18:31

标签: matlab matrix vectorization

我提出了一个有趣且有用的问题,需要在MATLAB中进行。它是关于编程的效率,避免使用循环"

假设矩阵URm 产品 。矩阵条目对这些产品的人员评级,并且此矩阵稀疏,因为每个人通常只评估少数产品。

 URm  [n_u, n_i]

另一个感兴趣的矩阵是F,其中包含每个产品的属性,属性具有固定长度:

 F  [n_f,n_i]

我们将URm随机分为两个子矩阵:URmTrainURmTest,其中前者用于训练系统,后者用于测试。这两个矩阵具有相似的行(用户),但它们可以具有不同数量的列(产品)。

我们可以使用pdist()或Matrix转置非常快速地找到项目之间的相似性:

 S = F * F' ; 

对于URmTest中的每一行(用户):

URmTestp = zeros(size(URmTest));
u = 1 ;   %% Example user 1

for i = 1 : size(URmTest,2)
indTrain = find(URmTrain(u,:)) ;   % For each user, search for items  in URmTrain that have been rated by the the user (i.e. the have a rating greater than zero)
  for j = 1 : length(indTrain)
    URmTestp(u,i) = URmTestp(u,i) + S(i,indTrain(j))*URmTrain(u,indTrain(j))
  end
end

其中URmpURm的预测版本,我们可以计算出预测有多好的错误。

示例

让我们举一个简单的例子。让我们假设用户1对项目3,5和17进行了评分:

indTrain = [3 5 17]

对于j中的每个项URmTest,我想使用以下公式预测评分:

URmTestp(u,j) = S(j,3)*URmTrain(u,3) + S(j,5)*URmTrain(u,5) + S(j,17)*URmTrain(u,17)

完成此过程后,需要为所有用户重复此过程。

由于URm通常非常大,我更喜欢使用最少量“循环”的选项。我们或许可以利用bsxfun,但我不确定是否可以。

请建议我尽快帮助加快这一过程。谢谢

1 个答案:

答案 0 :(得分:1)

我仍然不确定我完全理解你的问题。但在我看来,如果你预先计算s_ij

s_ij = F.' * F   %'// [ni x ni] matrix

那么你所追求的只是

URmTestp(u,indTest) = URmTrain(u,indTrain) * s_ij(indTrain,indTest);
% or
%URmTestp(u,:) = URmTrain(u,indTrain) * s_ij(indTrain,:);

或者如果您只为必要的数组计算较小的s_ij块,

s_ij = F(:,indTrain).' * F(:,indTest);

然后

URmTestp(u,indTest) = URmTrain(u,indTrain) * s_ij;

或者,您可以随时计算s_ij的必要子块:

URmTestp(u,indTest) = URmTrainp(u,indTrain) * F(:,indTrain).'*F(:,indTest);

如果我理解正确indTestindTrainu的功能,例如

URmTestp = zeros(n_u,n_i);  %// pre-allocate here!
for u=1:n_u
    indTest = testCell{u};
    indTrain = trainCell{u};
    URmTestp(u,indTest) = URmTrainp(u,indTrain) * F(:,indTrain).'*F(:,indTest); %'
    ...
end

然后在这个循环中可能没有多少可以被矢量化,除非有非常棘手的索引方案允许你使用线性索引。我坚持这个设置。