Skip to content

Instantly share code, notes, and snippets.

@lazybios
Forked from otobrglez/jaccard_recommendation.rb
Last active September 18, 2015 06:13
Show Gist options
  • Save lazybios/8912370e94e9df242863 to your computer and use it in GitHub Desktop.
Save lazybios/8912370e94e9df242863 to your computer and use it in GitHub Desktop.
Simple recommendation system written in Ruby based on Jaccard index.
#!/usr/bin/env ruby
# Please read http://otobrglez.opalab.com for more information about this code.
class Book < Struct.new(:title)
def words
@words ||= self.title.gsub(/[a-zA-Z]{3,}/).map(&:downcase).uniq.sort
end
end
class BookRecommender
def initialize book, books
@book, @books = book, books
end
def recommendations
@books.map! do |this_book|
this_book.define_singleton_method(:jaccard_index) do @jaccard_index; end
this_book.define_singleton_method("jaccard_index=") do |index|
@jaccard_index = index || 0.0
end
intersection = (@book.words & this_book.words).size
union = (@book.words | this_book.words).size
this_book.jaccard_index = (intersection.to_f / union.to_f) rescue 0.0
this_book
end.sort_by { |book| 1 - book.jaccard_index }
end
end
# Usage
# Load books from this file
BOOKS = DATA.read.split("\n").map { |l| Book.new(l) }
# Create initial book
this_book = Book.new("Ruby programming language")
# Load recommender
recommender = BookRecommender.new(this_book, BOOKS)
# Find recommendations
recommended_books = recommender.recommendations
# Show books that match the most
recommended_books.each do |book|
puts "#{book.title} (#{'%.2f' % book.jaccard_index})"
end
__END__
Finding the best language for the job
Could Ruby save the day
Python will rock your world
Is Ruby better than Python
Programming in Ruby is fun
Python to the moon
Programming languages of the future
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment