使用map reduce的用户到用户的相似性

时间:2012-05-12 07:10:04

标签: mongodb mapreduce

我的收藏包含:

{ 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提高代码效率?

此致

1 个答案:

答案 0 :(得分:2)

首先,你做2个mapreduces。

    • map:省略product_id作为键,将user_id作为值
    • reduce:循环遍历循环中的值列表(每个产品的用户ID列表)并省略为用户ID的密钥对(其中最小的用户ID是第一个)和值1
  1. (处理第一张地图缩小的结果)

    • map:只传递一对用户作为键,值1作为值
    • reduce:将每对的值相加。
  2. 其次,你不能比O(n2)更有效,因为你的结果是O(n2)的顺序。 意思是,即使以某种神奇的方式,你将获得对和相似性,你仍然需要写n ^ 2对。