class RecommEngine::Recommender

Attributes

data[R]
predicted_scores[R]
similarity_algorithm[R]
subject[R]
sum_of_user_similarity_scores_by_item[R]
sum_of_weighted_scores_by_item[R]
user_similarity_scores[R]

Public Class Methods

new(data:, subject:, similarity: RecommEngine::DEFAULT_ALGORITHM) click to toggle source
# File lib/recommengine/recommender.rb, line 5
def initialize(data:, subject:, similarity: RecommEngine::DEFAULT_ALGORITHM)
  @data = data
  @subject = subject
  @similarity_algorithm = similarity
  @predicted_scores = {}
  @user_similarity_scores = {}
  @sum_of_weighted_scores_by_item = {}
  @sum_of_user_similarity_scores_by_item = {}
  @sum_of_weighted_scores_by_item.default = 0
  @sum_of_user_similarity_scores_by_item.default = 0
end

Public Instance Methods

recs() click to toggle source
# File lib/recommengine/recommender.rb, line 17
def recs
  calculate_weighted_totals
  calculate_predicted_scores
  predicted_scores.sort_by{ |item, score| score }.reverse
end
top_rec() click to toggle source
# File lib/recommengine/recommender.rb, line 23
def top_rec
  calculate_weighted_totals
  calculate_predicted_scores
  predicted_scores.max_by{ |item, score| score }
end

Private Instance Methods

average_weighted_similarity_score(item, sum_of_scores) click to toggle source
# File lib/recommengine/recommender.rb, line 74
def average_weighted_similarity_score(item, sum_of_scores)
  sum_of_scores / sum_of_user_similarity_scores_by_item[item]
end
calculate_predicted_scores() click to toggle source
# File lib/recommengine/recommender.rb, line 57
def calculate_predicted_scores
  sum_of_weighted_scores_by_item.each { |item, sum_of_scores| predicted_scores[item] = average_weighted_similarity_score(item, sum_of_scores) }
end
calculate_weighted_totals() click to toggle source
# File lib/recommengine/recommender.rb, line 31
def calculate_weighted_totals
  comparates.each do |comparate|
    data[comparate].each_key{ |item| update_cumulative_totals(comparate, item) unless scored_by_subject?(item) }
  end
end
calculator_data(comparate) click to toggle source
# File lib/recommengine/recommender.rb, line 53
def calculator_data(comparate)
  data.select{ |user, item| user == subject || user == comparate }
end
comparates() click to toggle source
# File lib/recommengine/recommender.rb, line 37
def comparates
  data.dup.delete_if{ |user, item| user == subject || non_positive_similarity?(user) }.keys
end
non_positive_similarity?(comparate) click to toggle source
# File lib/recommengine/recommender.rb, line 41
def non_positive_similarity?(comparate)
  similarity_score(comparate) <= 0
end
scored_by_subject?(item) click to toggle source
# File lib/recommengine/recommender.rb, line 61
def scored_by_subject?(item)
  data[subject][item] && !data[subject][item].zero?
end
similarity_calculator() click to toggle source
# File lib/recommengine/recommender.rb, line 49
def similarity_calculator
  Module.const_get("RecommEngine::#{similarity_algorithm}Calculator")
end
similarity_score(comparate) click to toggle source
# File lib/recommengine/recommender.rb, line 45
def similarity_score(comparate)
  user_similarity_scores[comparate] ||= similarity_calculator.new(data: calculator_data(comparate), subject: subject, comparate: comparate).calc
end
update_cumulative_totals(comparate, item) click to toggle source
# File lib/recommengine/recommender.rb, line 65
def update_cumulative_totals(comparate, item)
  sum_of_weighted_scores_by_item[item] += weighted_similarity_score(comparate, item)
  sum_of_user_similarity_scores_by_item[item] += similarity_score(comparate)
end
weighted_similarity_score(comparate, item) click to toggle source
# File lib/recommengine/recommender.rb, line 70
def weighted_similarity_score(comparate, item)
  data[comparate][item] * similarity_score(comparate)
end