Skip to content

Instantly share code, notes, and snippets.

@timyates
Created March 24, 2014 14:16
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save timyates/9740927 to your computer and use it in GitHub Desktop.
Save timyates/9740927 to your computer and use it in GitHub Desktop.
Simple recommendation system written in Groovy based on Jaccard index.
import groovy.transform.*
@Immutable
class Book {
String title
@Memoized LinkedHashSet<String> getWords() {
title.findAll( /[a-zA-Z]{3,}/ ).collect { it.toLowerCase() }.sort() as LinkedHashSet
}
}
@Immutable
class BookRecommender {
Book book
List<Book> books
def getRecommendations() {
books.collect { aBook ->
double intersection = book.words.intersect( aBook.words ).size()
double union = ( book.words + aBook.words ).size()
aBook.metaClass.getJaccardIndex = { -> intersection / union }
aBook
}.sort { -it.jaccardIndex }
}
}
def books = '''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'''.stripMargin()
.split( '\n' )
.collect { new Book( it ) }
def target = new Book( 'Ruby programming language' )
def recommender = new BookRecommender( target, books )
recommender.recommendations.each {
println "$it.title (${String.format( '%.02f', it.jaccardIndex)})"
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment