使用地图减少的用户与用户相似性



我的收藏包含:

{ 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 },

编辑

我已经在没有地图减少的情况下做到了

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(n2),其中 n 是用户数。
如何使用map-reduce使我的代码更有效率?

问候

首先,你做 2 个 mapreduce。

    • map:省略product_id作为键,省略user_id作为值
    • Reduce:循环循环迭代值列表(每个产品的用户 ID 列表),并省略作为用户 ID 的键对(其中最小的用户 ID 是第一个)和值 1
  1. (处理第一张地图归约的结果)

    • map:只需将用户对作为键传递,将值 1 作为值传递
    • 化简:对每对的值求和。

其次,你不能比 O(n2) 更有效率,因为你的结果是 O(n2) 的顺序。意思是,即使以某种神奇的方式,你会得到对和相似性,你仍然需要写 n^2 对。

相关内容

  • 没有找到相关文章

最新更新