class Recommendation::Recommender

Attributes

table[RW]

Public Class Methods

new(params = {}) click to toggle source
# File lib/recommendation/recommender.rb, line 8
def initialize(params = {})
  @table = params
end
recommendation(table, user, similarity=:sim_pearson) click to toggle source
# File lib/recommendation/recommender.rb, line 28
def recommendation(table, user, similarity=:sim_pearson)
  totals_h = Hash.new(0)
  sim_sums_h = Hash.new(0)
  table.each do |other, val|
    next if other == user
    sim = __send__(similarity, table, user, other)
    next if sim <= 0
    table[other].each do |item, val|
      if !table[user].keys.include?(item) || table[user][item] == 0
        totals_h[item] += table[other][item]*sim
        sim_sums_h[item] += sim
      end
    end
  end

  rankings = Hash.new
  totals_h.each do |item, total|
    rankings[item] = total/sim_sums_h[item]
  end

  rankings.sort_by{|k, v| -v}
end
top_matches(table, user, n=5, similarity=:sim_pearson) click to toggle source
# File lib/recommendation/recommender.rb, line 51
def top_matches(table, user, n=5, similarity=:sim_pearson)
  scores = Array.new
  table.each do |key, value|
    if key != user
      scores << [__send__(similarity, table, user,key), key]
    end
  end

  result = Array.new
  scores.sort.reverse[0,n].each do |k, v|
    result << [v, k]
  end
  result
end

Private Class Methods

shared_items(table, user1, user2) click to toggle source
# File lib/recommendation/recommender.rb, line 98
def shared_items(table, user1, user2)
  shared_items_h = Hash.new
  table[user1].each do |k, v|
    shared_items_h[k] = 1 if table[user2].include?(k)
  end
  shared_items_h
end
shared_items_a(table, user1, user2) click to toggle source
# File lib/recommendation/recommender.rb, line 106
def shared_items_a(table, user1, user2)
  table[user1].nil? ? [] : table[user1].keys & table[user2].keys
end
sim_pearson(table, user1, user2) click to toggle source
# File lib/recommendation/recommender.rb, line 68
def sim_pearson(table, user1, user2)
  shared_items_a = shared_items_a(table, user1, user2)

  n = shared_items_a.size
  return 0 if n == 0

  sum1 = shared_items_a.inject(0) {|result, si|
    result + table[user1][si]
  }
  sum2 = shared_items_a.inject(0) {|result, si|
    result + table[user2][si]
  }

  sum1_sq = shared_items_a.inject(0) {|result, si|
    result + table[user1][si]**2
  }
  sum2_sq = shared_items_a.inject(0) {|result, si|
    result + table[user2][si]**2
  }

  sum_products = shared_items_a.inject(0) {|result, si|
    result + table[user1][si]*table[user2][si]
  }

  num = sum_products - (sum1*sum2/n)
  den = Math.sqrt((sum1_sq - sum1**2/n)*(sum2_sq - sum2**2/n))
  return 0 if den == 0
  return num/den
end

Public Instance Methods

train(params = {}) click to toggle source
# File lib/recommendation/recommender.rb, line 12
def train(params = {})
  @table.merge!(params)
end
transform_table() click to toggle source
# File lib/recommendation/recommender.rb, line 16
def transform_table
  new_table = {}
  @table.each do |key, value|
    value.each do |new_key, new_value|
      new_table[new_key] ||= Hash.new
      new_table[new_key][key] = new_value
    end
  end
  new_table
end