lolamontes69

recommendations.py used in Collective Intelligence exercises

May 19th, 2013
63
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 6.12 KB | None | 0 0
  1. # A dictionary of movie critics and thie ratings of a small
  2. # set of movies
  3. critics = {'Lisa Rose': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.5, 'Just My Luck': 3.0, 'Superman Returns': 3.5, 'You, Me and Dupree': 2.5, 'The Night Listener': 3.0},'Gene Seymour': {'Lady in the Water': 3.0, 'Snakes on a Plane': 3.5, 'Just My Luck': 1.5, 'Superman Returns': 5.0, 'You, Me and Dupree': 3.5, 'The Night Listener': 3.0},'Michael Phillips': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.0, 'Superman Returns': 3.5, 'The Night Listener': 4.0},'Claudia Puig': {'Snakes on a Plane': 3.5, 'Just My Luck': 3.0, 'Superman Returns': 4.0, 'You, Me and Dupree': 2.5, 'The Night Listener': 4.5},'Mick LaSalle': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0, 'Just My Luck': 2.0, 'Superman Returns': 3.0, 'You, Me and Dupree': 2.0, 'The Night Listener': 3.0},'Jack Mathews': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0, 'Superman Returns': 5.0, 'You, Me and Dupree': 3.5, 'The Night Listener': 3.0},'Toby': {'Snakes on a Plane': 4.5, 'Superman Returns': 4.0, 'You, Me and Dupree': 1.0}}
  4.  
  5. from math import sqrt
  6.  
  7. # Returns a distance-based similarity score for person1 and person2
  8. def sim_distance(prefs, person1, person2):
  9.     # Get the list of shared_items
  10.     si = {}
  11.     for item in prefs[person1]:
  12.         if item in prefs[person2]:
  13.             si[item] = 1
  14.  
  15.     # If they have no ratings in common, return 0
  16.     if len(si) == 0: return 0
  17.  
  18.     # Add up the squares of all the differences
  19.     sum_of_squares = sum([pow(prefs[person1][item]-prefs[person2][item],2) for item in prefs[person1] if item in prefs[person2]])
  20.     return 1/(1+sum_of_squares)
  21.  
  22. # Returns the Pearson correlation coefficient for p1 and p2
  23. def sim_pearson(prefs, p1, p2):
  24.     si = {}
  25.     for item in prefs[p1]:
  26.         if item in prefs[p2]: si[item] = 1
  27.  
  28.     # Find the number of elements
  29.     n = len(si)
  30.  
  31.     # If there are no ratings, return 0
  32.     if n == 0: return 0
  33.  
  34.     # Add up all the preferences
  35.     sum1 = sum([prefs[p1][it] for it in si])
  36.     sum2 = sum([prefs[p2][it] for it in si])
  37.  
  38.     # Sum up all the squares
  39.     sum1Sq = sum([pow(prefs[p1][it],2) for it in si])
  40.     sum2Sq = sum([pow(prefs[p2][it],2) for it in si])
  41.  
  42.     # Sum up the products
  43.     psum = sum([prefs[p1][it]*prefs[p2][it] for it in si])
  44.  
  45.     # Calculate Pearson score
  46.     num = psum-(sum1*sum2/n)
  47.     den = sqrt((sum1Sq-pow(sum1,2)/n)*(sum2Sq-pow(sum2,2)/n))
  48.     if den == 0: return 0
  49.  
  50.     r = num/den
  51.  
  52.     return r
  53.  
  54.     # Returns the best matches for person from the prefs dictionary
  55.     # Number of results and similarity function are optional params.
  56.  
  57. def topMatches(prefs, person, n=5, similarity=sim_pearson):
  58.     scores = [(similarity(prefs, person, other), other) for other in prefs if other!= person]
  59.  
  60.     # Sort the list so the highest scores appear at the top
  61.     scores.sort()
  62.     scores.reverse()
  63.     return scores[0:n]
  64.  
  65. # Gets recommendations for a person by using a weighted average
  66. # of every other user's rankings
  67. def getRecommendations(prefs, person, similarity=sim_pearson):
  68.     totals = {}
  69.     simSums = {}
  70.     for other in prefs:
  71.         # Don't compare me to myself
  72.         if other == person: continue
  73.         sim = similarity(prefs, person, other)
  74.  
  75.         # ignore scores of zero or lower
  76.         if sim <= 0: continue
  77.         for item in prefs[other]:
  78.  
  79.             # only score movies I haven't seen yet
  80.             if item not in prefs[person] or prefs[person][item] == 0:
  81.  
  82.             # Similarity * Score
  83.                 totals.setdefault(item,0)
  84.                 totals[item] += prefs[other][item]*sim
  85.  
  86.             # Sum of similarities
  87.                 simSums.setdefault(item,0)
  88.                 simSums[item] += sim
  89.  
  90.     # Create the normalized list
  91.     rankings = [(total/simSums[item],item) for item, total in totals.items()]
  92.  
  93.     # Return the sorted list
  94.     rankings.sort()
  95.     rankings.reverse()
  96.     return rankings
  97.  
  98. def transformPrefs(prefs):
  99.     result = {}
  100.     for person in prefs:
  101.         for item in prefs[person]:
  102.             result.setdefault(item,{})
  103.  
  104.             # Flip item and person
  105.             result[item][person] = prefs[person][item]
  106.     return result
  107.  
  108. def calculateSimilarItems(prefs, n=10):
  109.     # Create a dictionary of items showing which other items
  110.     # they are most similar to
  111.     result = {}
  112.  
  113.     # Invert the preference matrix to be item-centric
  114.     itemPrefs = transformPrefs(prefs)
  115.     c = 0
  116.     for item in itemPrefs:
  117.         # Status updates for large datasets
  118.         c += 1
  119.         if c%100 == 0: print "%d / %d" % (c, len(itemPrefs))
  120.         # Find the most similar items to this one
  121.         scores = topMatches(itemPrefs, item, n=n, similarity=sim_distance)
  122.         result[item] = scores
  123.     return result
  124.  
  125. def getRecommendedItems(prefs, itemMatch, user):
  126.     userRatings = prefs[user]
  127.     scores = {}
  128.     totalSim = {}
  129.  
  130.     # Loop over items rated by this user
  131.     for (item, rating) in userRatings.items():
  132.         # Loop over items similar to this one
  133.         for (similarity, item2) in itemMatch[item]:
  134.             # Ignore if this user has already rated this item
  135.             if item2 in userRatings: continue
  136.  
  137.             # Weighted sum of ratings times similarity
  138.             scores.setdefault(item2, 0)
  139.             scores[item2] += similarity*rating
  140.  
  141.             # Sum of all the similarities
  142.             totalSim.setdefault(item2, 0)
  143.             totalSim[item2] += similarity
  144.  
  145.     # Divide each total score by total weighting to get an average
  146.     rankings = [(score/totalSim[item], item) for item, score in scores.items()]
  147.  
  148.     # Return the rankings from highest to lowest
  149.     rankings.sort()
  150.     rankings.reverse()
  151.     return rankings
  152.    
  153.  
  154.  
  155. def loadMovieLens(path='./movielens'):
  156.  
  157.     # Get movies titles
  158.     movies = {}
  159.     for line in open(path+'/u.item'):
  160.         (id, title) = line.split('|')[0:2]
  161.         movies[id] = title
  162.  
  163.     # Load data
  164.     prefs = {}
  165.     for line in open(path+'/u.data'):
  166.         (user, movieid, rating, ts) = line.split('\t')
  167.         prefs.setdefault(user, {})
  168.         prefs[user][movies[movieid]] = float(rating)
  169.     return prefs
Advertisement
Add Comment
Please, Sign In to add comment