Programming Collective Intelligence
Posted by Sandro Paganotti in
Ruby on Rails -
comments are closed
Yesterday I started reading Programming Collective Intelligence and.. WOW ! This book is simply amazing.
At the moment I’m reading page 30 and in the chapter I’ve just finished I’ve learned how to create a simply yet powerful recommendations system that uses both euclidean distance and Pearson correlation score to determine the affinity between people based on how they have ranked objects.
For example you can measure the affinity between people based on how they rank movies or, with a little effort, the affinity between two movies based on how they have been ranked.
While reading this book I had to face a little trouble…
All the samples are written in Python!
and as you may have guessed I don’t know almost anything about this programming language. So, with the help of a good manual I’ve started to translate the code from Python to Ruby. The result after the first 30 pages is ready for you to download at the end of this post.
Recommendation.rb
This module contains the following functions:
- sim_distance(prefs, person1, person2)
It calculates an index between 0 (no affinity) and 1 (congruency) between person1 and person2 based on a set of preferences called prefs (explained at the end of this list ); - sim_pearson(prefs, person1, person2)
It does the same job as ‘sim distance’ but this time using the Pearson Correlation score; - top_matches(prefs,person,n=3,similarity=’sim_pearson’)
It returns a list of the first n people ordered by their affinity to person. You can also choose which similarity algorithm you want to use (default is sim_pearson).
the ‘prefs’ preference set must have the following structure:
prefs_hash = {
'personA' => { :item_1 => numeric_rank, :item_2 => numeric_rank },
'personB' => { :item_1 => numeric_rank, :item_2 => numeric_rank },
etc...
}
And here is a sample function call:
sim_distance(prefs_hash, 'personA', 'personB')
Here is the file – recommendation.rb.zip
As far as I keep reading I’m going to translate the samples of this book, so stay tuned.


Comments
A.B.Leal
Posted on January 15
Jamie Pitts
Posted on January 16
ms
Posted on January 16
ms
Posted on January 16
Riccardo Cambiassi
Posted on January 16
rb
Posted on January 18
alex
Posted on January 18
Sandro
Posted on January 24
@rb: I've fixed the recommendation.rb file according to your suggestion.
@alex: I'm going to contact you directly to share our passion for this book.
jason z
Posted on February 09
Bosco
Posted on February 10
Bosco
Posted on February 20
Sandro Paganotti
Posted on February 21
Bosco
Posted on February 23
def getRecommendations(prefs,person) totals={} simSums={} prefs.each do |other| # don't compare me to myself if other[0]==person next end sim=sim_pearson(prefs,person,other[0]) # ignore scores of zero or lower if sim<=0 next end prefs[other[0]].each do |item| event=item[0] # only score movies I haven't seen yet if (not prefs[person].include?(event) or prefs[person][event]==0) # Similarity * Score if totals[event] == nil totals[event]=0 end totals[event]=totals[event]+prefs[other[0]][event]*sim # Sum of similarities if simSums[event] == nil simSums[event]=0 end simSums[event]+=sim end end end # Create the normalized list rankings=[] totals.each do |total| rankings << {total[0],total[1]/simSums[total[0]]} end # Return the sorted list # rankings.sort{|x,y| x[1]<=>y[1]} # rankings.reverse() return rankings endBosco
Posted on February 23