我提出了一个有趣且有用的问题,需要在MATLAB中进行。它是关于编程的效率,避免使用循环"
假设矩阵URm
的列 产品且行 人。矩阵条目对这些产品的人员评级,并且此矩阵稀疏,因为每个人通常只评估少数产品。
URm [n_u, n_i]
另一个感兴趣的矩阵是F
,其中包含每个产品的属性,属性具有固定长度:
F [n_f,n_i]
我们将URm
随机分为两个子矩阵:URmTrain
和URmTest
,其中前者用于训练系统,后者用于测试。这两个矩阵具有相似的行(用户),但它们可以具有不同数量的列(产品)。
我们可以使用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
其中URmp
是URm
的预测版本,我们可以计算出预测有多好的错误。
示例
让我们举一个简单的例子。让我们假设用户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
,但我不确定是否可以。
请建议我尽快帮助加快这一过程。谢谢
答案 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);
如果我理解正确indTest
和indTrain
是u
的功能,例如
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
然后在这个循环中可能没有多少可以被矢量化,除非有非常棘手的索引方案允许你使用线性索引。我坚持这个设置。