我的收藏包含:
{ user_id : 1, product_id : 1 },
{ user_id : 1, product_id : 2 },
{ user_id : 1, product_id : 3 },
{ user_id : 2, product_id : 2 },
{ user_id : 2, product_id : 3 },
{ user_id : 3, product_id : 2 },
我的收集跟踪产品由用户查看, user_id 是用户ID, product_id 是产品ID。
我想计算两个用户之间的相似性,例如他们都看过的产品数量
例如,从上面的集合中,用户之间的相似性将是
{ user_id1 : 1, user_id2 : 2, similarity : 2 },
{ user_id1 : 1, user_id2 : 3, similarity : 1 },
{ user_id1 : 2, user_id2 : 3, similarity : 1 },
我没有map-reduce
就完成了def self.build_similarity_weight
users_id = ProductView.all.distinct(:user_id).to_a
users_id.each do |user_id|
this_user_products = ProductView.all.where(user_id: user_id).distinct(:product_id).to_a
other_users = users_id.map { |e| e }
other_users.delete_if { |x| x == user_id }
other_users.each do |other_uid|
other_user_products = ProductView.all.where(user_id: other_uid).distinct(:product_id).to_a
user_sim = (other_user_products & this_user_products).length
usw = UserSimilarityWeight.new(user_id1: user_id, user_id2: other_uid, weight: user_sim)
usw.save
end
end
end
问题是我的代码效率不高, O(n 2 ),其中 n 是用户数。
如何使用map-reduce提高代码效率?
此致
答案 0 :(得分:2)
首先,你做2个mapreduces。
(处理第一张地图缩小的结果)
其次,你不能比O(n2)更有效,因为你的结果是O(n2)的顺序。 意思是,即使以某种神奇的方式,你将获得对和相似性,你仍然需要写n ^ 2对。