{ "metadata": { "name": "12notes" }, "nbformat": 3, "nbformat_minor": 0, "worksheets": [ { "cells": [ { "cell_type": "code", "collapsed": false, "input": [ "#this follows chpt2 of\n", "#\"Programming Collective Intelligence\", by T. Segaran\n", "##ask your friends, weight according to similarity" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 1 }, { "cell_type": "code", "collapsed": false, "input": [ "from scipy import stats\n", "#r,p=stats.pearsonr(xdata,ydata)\n", "#slope, intercept, r_value, p_value, std_err = stats.linregress(xdata,ydata)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 2 }, { "cell_type": "code", "collapsed": false, "input": [ "# A dictionary of movie critics and their ratings of a small set of movies\n", "critics={'Lisa Rose': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.5,\n", " 'Just My Luck': 3.0, 'Superman Returns': 3.5, 'You, Me and Dupree': 2.5, \n", " 'The Night Listener': 3.0},\n", "'Gene Seymour': {'Lady in the Water': 3.0, 'Snakes on a Plane': 3.5, \n", " 'Just My Luck': 1.5, 'Superman Returns': 5.0, 'The Night Listener': 3.0, \n", " 'You, Me and Dupree': 3.5}, \n", "'Michael Phillips': {'Lady in the Water': 2.5, 'Snakes on a Plane': 3.0,\n", " 'Superman Returns': 3.5, 'The Night Listener': 4.0},\n", "'Claudia Puig': {'Snakes on a Plane': 3.5, 'Just My Luck': 3.0,\n", " 'The Night Listener': 4.5, 'Superman Returns': 4.0, \n", " 'You, Me and Dupree': 2.5},\n", "'Mick LaSalle': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0, \n", " 'Just My Luck': 2.0, 'Superman Returns': 3.0, 'The Night Listener': 3.0,\n", " 'You, Me and Dupree': 2.0}, \n", "'Jack Matthews': {'Lady in the Water': 3.0, 'Snakes on a Plane': 4.0,\n", " 'The Night Listener': 3.0, 'Superman Returns': 5.0, 'You, Me and Dupree': 3.5},\n", "'Toby': {'Snakes on a Plane':4.5,'You, Me and Dupree':1.0,'Superman Returns':4.0}}" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 3 }, { "cell_type": "code", "collapsed": false, "input": [ "len(critics), map(len,critics.values())" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 4, "text": [ "(7, [5, 6, 5, 6, 3, 6, 4])" ] } ], "prompt_number": 4 }, { "cell_type": "code", "collapsed": false, "input": [ "#what has Toby reviewed:\n", "critics['Toby']" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 5, "text": [ "{'Snakes on a Plane': 4.5, 'Superman Returns': 4.0, 'You, Me and Dupree': 1.0}" ] } ], "prompt_number": 5 }, { "cell_type": "code", "collapsed": false, "input": [ "#look at just the critics who reviewed these two movies\n", "dupree='You, Me and Dupree'\n", "snakes='Snakes on a Plane'\n", "ds={c.split()[-1]:(critics[c][dupree],critics[c][snakes])\n", " for c in critics if dupree in critics[c] and snakes in critics[c]}\n", "ds" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 6, "text": [ "{'LaSalle': (2.0, 4.0),\n", " 'Matthews': (3.5, 4.0),\n", " 'Puig': (2.5, 3.5),\n", " 'Rose': (2.5, 3.5),\n", " 'Seymour': (3.5, 3.5),\n", " 'Toby': (1.0, 4.5)}" ] } ], "prompt_number": 6 }, { "cell_type": "code", "collapsed": false, "input": [ "#now plot them\n", "figure(figsize=(5,5))\n", "xlim(0,5)\n", "ylim(0,5)\n", "offset={c:.01 for c in ds}\n", "offset['Rose']=0\n", "offset['Puig']=-.15 #move Puig down to avoid collision\n", "plot([ds[crit][0] for crit in ds],[ds[crit][1] for crit in ds],'o')\n", "for crit in ds: text(ds[crit][0]+.05,ds[crit][1]+offset[crit],crit)\n", "xlabel('dupree')\n", "ylabel('snakes');" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "display_data", "png": "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\n" } ], "prompt_number": 7 }, { "cell_type": "code", "collapsed": false, "input": [ "#who's close to whom in the above fig?\n", "# Returns a distance-based similarity score for person1 and person2\n", "def sim_distance(prefs,person1,person2):\n", " # Get the list of shared_items\n", " si=[item for item in prefs[person1] if item in prefs[person2]]\n", "\n", " # if they have no ratings in common, return 0\n", " if len(si)==0: return 0\n", " \n", " v1=array([prefs[person1][item] for item in si])\n", " v2=array([prefs[person2][item] for item in si])\n", "\n", " # use numpy euclidean distance (sqrt(sum of squares))\n", " dist=norm(v1-v2)\n", "\n", " #transform to similarity ranging from 0 to 1\n", " #truncate to three after decimal point\n", " return float(\"%.3f\" % (1/(1+dist**2))) " ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 8 }, { "cell_type": "code", "collapsed": false, "input": [ "sim_distance(critics,'Lisa Rose','Gene Seymour')" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 9, "text": [ "0.148" ] } ], "prompt_number": 9 }, { "cell_type": "code", "collapsed": false, "input": [ "#consider a different distance measure,\n", "# Pearson correlation coefficient\n", "#[+1 if correlated, -1 if anticorrelated]\n", "def show_pearson(prefs,c1,c2):\n", " si=[item for item in prefs[c1] if item in prefs[c2]]\n", "\n", " figure(figsize=(5,5))\n", " xlim(0,5)\n", " ylim(0,5)\n", " xdata = [prefs[c1][item] for item in si]\n", " ydata = [prefs[c2][item] for item in si]\n", "\n", " slope, intercept, r_value, p_value, std_err = stats.linregress(xdata,ydata)\n", " print 'pearson r =', '%.2f'%r_value\n", "\n", " xlabel(c1)\n", " ylabel(c2)\n", " \n", " plot(xdata,ydata,'o')\n", " plot(slope*array(range(0,6))+intercept,'--')\n", " for item in si:\n", " text(prefs[c1][item],prefs[c2][item],item)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 10 }, { "cell_type": "code", "collapsed": false, "input": [ "#two fake critics roughly correlated\n", "fcritics={'critic1':{'Dupree':1,'Night':2.5,'Lady':3,'Snakes':3.5,'Superman':4.5},\n", " 'critic2':{'Dupree':2,'Night':3,'Lady':2.5,'Snakes':3.5,'Superman':3.5}}\n", "show_pearson(fcritics,'critic1','critic2')" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "pearson r = 0.87\n" ] }, { "output_type": "display_data", "png": "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\n" } ], "prompt_number": 11 }, { "cell_type": "code", "collapsed": false, "input": [ "#two from original set not quite as well correlated\n", "show_pearson(critics,'Mick LaSalle','Gene Seymour')" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "pearson r = 0.41\n" ] }, { "output_type": "display_data", "png": "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\n" } ], "prompt_number": 12 }, { "cell_type": "code", "collapsed": false, "input": [ "#now define similarity measure, analogous to sim_distance\n", "def sim_pearson(prefs,c1,c2):\n", " si=[item for item in prefs[c1] if item in prefs[c2]]\n", " if len(si)==0: return 0\n", " xdata = [prefs[c1][item] for item in si]\n", " ydata = [prefs[c2][item] for item in si]\n", " r,p=stats.pearsonr(xdata,ydata)\n", " if isnan(r): return 0\n", " return float(\"%.3f\"%r)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 13 }, { "cell_type": "code", "collapsed": false, "input": [ "#note pearson corrects for \"grade inflation\", unlike euclidean distance\n", "#one can be systematically higher than the other, offset won't matter" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 14 }, { "cell_type": "code", "collapsed": false, "input": [ "#now rank the critics, finding ones with similar taste\n", "\n", "# Returns the best matches for person from the prefs dictionary. \n", "# Number of results and similarity function are optional params.\n", "def topMatches(prefs, person, n=5, similarity=sim_pearson):\n", " scores=[(other, similarity(prefs,person,other))\n", " for other in prefs if other!=person]\n", " return sorted(scores,key=lambda x:x[1],reverse=True)[:n]" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 15 }, { "cell_type": "code", "collapsed": false, "input": [ "topMatches(critics,'Toby',n=6)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 16, "text": [ "[('Lisa Rose', 0.991),\n", " ('Mick LaSalle', 0.924),\n", " ('Claudia Puig', 0.893),\n", " ('Jack Matthews', 0.663),\n", " ('Gene Seymour', 0.381),\n", " ('Michael Phillips', -1.0)]" ] } ], "prompt_number": 16 }, { "cell_type": "code", "collapsed": false, "input": [ "# see how topmatches function works using other similarity measure\n", "topMatches(critics,'Toby', n=3, similarity=sim_distance)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 17, "text": [ "[('Mick LaSalle', 0.308), ('Michael Phillips', 0.286), ('Claudia Puig', 0.235)]" ] } ], "prompt_number": 17 }, { "cell_type": "code", "collapsed": false, "input": [ "#but really want recommendation. could use just most similar person, but that person\n", "#might not have seen relevant movie, or might be outlier on particular movie, instead:" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "# Gets recommendations for a person by using a weighted average\n", "# of every other user's rankings\n", "def getRecommendations(prefs,person,similarity=sim_pearson):\n", " totals={}\n", " simSums={}\n", " for other in prefs:\n", " # don't compare me to myself\n", " if other==person: continue\n", " sim=similarity(prefs,person,other)\n", " \n", " # ignore scores of zero or lower\n", " if sim<=0: continue\n", " for item in prefs[other]:\n", "\n", " # only score movies I haven't seen yet\n", " if item not in prefs[person] or prefs[person][item]==0:\n", " # Similarity * Score\n", " if item not in totals:\n", " totals[item]=0\n", " simSums[item]=0\n", " totals[item] += prefs[other][item]*sim\n", " # Sum of similarities\n", " simSums[item] += sim\n", "\n", " # Create the normalized list\n", " rankings=[(item,float(\"%.3f\"%(totals[item]/simSums[item]))) for item in totals]\n", "\n", " # Return the sorted list\n", " return sorted(rankings,key=lambda x:x[1],reverse=True)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 18 }, { "cell_type": "code", "collapsed": false, "input": [ "getRecommendations(critics,'Toby')\n", "#also gives likely rating" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 19, "text": [ "[('The Night Listener', 3.348),\n", " ('Lady in the Water', 2.833),\n", " ('Just My Luck', 2.531)]" ] } ], "prompt_number": 19 }, { "cell_type": "code", "collapsed": false, "input": [ "#or use other distance measure\n", "getRecommendations(critics,'Toby',similarity=sim_distance)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 20, "text": [ "[('The Night Listener', 3.5),\n", " ('Lady in the Water', 2.756),\n", " ('Just My Luck', 2.462)]" ] } ], "prompt_number": 20 }, { "cell_type": "code", "collapsed": false, "input": [ "#now suppose you want matching products, i.e., amazon \"customers have also bought\"" ], "language": "python", "metadata": {}, "outputs": [] }, { "cell_type": "code", "collapsed": false, "input": [ "#first reverse role of items and objects\n", "def transformPrefs(prefs):\n", " result={}\n", " for person in prefs:\n", " for item in prefs[person]:\n", " if item not in result: result[item]={}\n", " \n", " # Flip item and person\n", " result[item][person]=prefs[person][item]\n", " return result" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 21 }, { "cell_type": "code", "collapsed": false, "input": [ "movies=transformPrefs(critics)\n", "movies" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 22, "text": [ "{'Just My Luck': {'Claudia Puig': 3.0,\n", " 'Gene Seymour': 1.5,\n", " 'Lisa Rose': 3.0,\n", " 'Mick LaSalle': 2.0},\n", " 'Lady in the Water': {'Gene Seymour': 3.0,\n", " 'Jack Matthews': 3.0,\n", " 'Lisa Rose': 2.5,\n", " 'Michael Phillips': 2.5,\n", " 'Mick LaSalle': 3.0},\n", " 'Snakes on a Plane': {'Claudia Puig': 3.5,\n", " 'Gene Seymour': 3.5,\n", " 'Jack Matthews': 4.0,\n", " 'Lisa Rose': 3.5,\n", " 'Michael Phillips': 3.0,\n", " 'Mick LaSalle': 4.0,\n", " 'Toby': 4.5},\n", " 'Superman Returns': {'Claudia Puig': 4.0,\n", " 'Gene Seymour': 5.0,\n", " 'Jack Matthews': 5.0,\n", " 'Lisa Rose': 3.5,\n", " 'Michael Phillips': 3.5,\n", " 'Mick LaSalle': 3.0,\n", " 'Toby': 4.0},\n", " 'The Night Listener': {'Claudia Puig': 4.5,\n", " 'Gene Seymour': 3.0,\n", " 'Jack Matthews': 3.0,\n", " 'Lisa Rose': 3.0,\n", " 'Michael Phillips': 4.0,\n", " 'Mick LaSalle': 3.0},\n", " 'You, Me and Dupree': {'Claudia Puig': 2.5,\n", " 'Gene Seymour': 3.5,\n", " 'Jack Matthews': 3.5,\n", " 'Lisa Rose': 2.5,\n", " 'Mick LaSalle': 2.0,\n", " 'Toby': 1.0}}" ] } ], "prompt_number": 22 }, { "cell_type": "code", "collapsed": false, "input": [ "#now topmatches gives similar movies rather than similar reviewers\n", "topMatches(movies,'Superman Returns')" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 23, "text": [ "[('You, Me and Dupree', 0.658),\n", " ('Lady in the Water', 0.488),\n", " ('Snakes on a Plane', 0.112),\n", " ('The Night Listener', -0.18),\n", " ('Just My Luck', -0.423)]" ] } ], "prompt_number": 23 }, { "cell_type": "code", "collapsed": false, "input": [ "#note negative scores, reviews who like one dislike the other\n", "show_pearson(movies,'Just My Luck','Superman Returns')" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "pearson r = -0.42\n" ] }, { "output_type": "display_data", "png": "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\nkWwxAIlItv4fIG9QKgbfM0wAAAAASUVORK5CYII=\n" } ], "prompt_number": 24 }, { "cell_type": "code", "collapsed": false, "input": [ "getRecommendations(movies,'Just My Luck')\n", "#find critics for movie ... invite to premiere?" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 25, "text": [ "[('Michael Phillips', 4.0), ('Jack Matthews', 3.0)]" ] } ], "prompt_number": 25 }, { "cell_type": "code", "collapsed": false, "input": [ "#now apply to de.licio.us data\n", "# python code to interact with delicious api is here\n", "#http://code.google.com/p/pydelicious/source\n", "#svn checkout http://pydelicious.googlecode.com/svn/trunk/ pydelicious\n", "#sudo python setup.py install\n", "from pydelicious import get_popular,get_userposts,get_urlposts\n", "import time" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 26 }, { "cell_type": "code", "collapsed": false, "input": [ "#function to get some users from the most popular posts\n", "def initializeUserDict(tag,count=5):\n", " user_dict={}\n", " # get the top count popular posts\n", " for p1 in get_popular(tag=tag)[0:count]:\n", " print 'p1=',{k:v.encode('ascii','ignore') for k,v in p1.items()}\n", " # find all users who posted this\n", " for p2 in get_urlposts(p1['url']):\n", " user=p2['user']\n", " userasc=user.encode('ascii','ignore')\n", " if user == userasc and len(user)>1: user_dict[userasc]={}\n", " return user_dict" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 27 }, { "cell_type": "code", "collapsed": false, "input": [ "#get users from ten urls with 'programming' tag\n", "del_users = initializeUserDict('programming',10)\n", "print len(del_users.keys()),'users'" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "p1= {'extended': '', 'description': 'Gmail Email Analysis with Neo4j - and Spreadsheets | Architects Zone', 'tags': 'programming', 'url': 'http://architects.dzone.com/articles/gmail-email-analysis-neo4j-and', 'user': '', 'dt': ''}\n", "p1=" ] }, { "output_type": "stream", "stream": "stdout", "text": [ " {'extended': '', 'description': '10 Questions to Ask When Hiring a Mobile App Developer | YoungEntrepreneur.com', 'tags': 'programming', 'url': 'http://www.youngentrepreneur.com/startingup/leadership-qualities-skills/10-questions-to-ask-when-hiring-a-mobile-app-developer/', 'user': '', 'dt': ''}\n", "p1=" ] }, { "output_type": "stream", "stream": "stdout", "text": [ " {'extended': '', 'description': 'The Web API Checklist 43 Things To Think About When Designing, Testing, and Releasing your API | Mathieu Fenniak', 'tags': 'api', 'url': 'http://mathieu.fenniak.net/the-api-checklist/', 'user': '', 'dt': ''}\n", "p1=" ] }, { "output_type": "stream", "stream": "stdout", "text": [ " {'extended': '', 'description': 'www.hyperpolyglot.org', 'tags': 'comparatif', 'url': 'http://www.hyperpolyglot.org/', 'user': '', 'dt': ''}\n", "p1=" ] }, { "output_type": "stream", "stream": "stdout", "text": [ " {'extended': '', 'description': 'image.diku.dk', 'tags': 'programming', 'url': 'http://image.diku.dk/shark/sphinx_pages/build/html/index.html?utm_source=feedly', 'user': 'salloo', 'dt': ''}\n", "p1=" ] }, { "output_type": "stream", "stream": "stdout", "text": [ " {'extended': '', 'description': 'P2PU | Python for Informatics | Chapter 9 - Dictionaries', 'tags': 'python', 'url': 'https://p2pu.org/en/courses/175/content/407/', 'user': '', 'dt': ''}\n", "p1=" ] }, { "output_type": "stream", "stream": "stdout", "text": [ " {'extended': '', 'description': 'Educator Intermediate Level C++ with Alvin Sylvain', 'tags': 'programming', 'url': 'http://tutolearning.com/educator-intermediate-level-c-with-alvin-sylvain/', 'user': '', 'dt': ''}\n", "p1=" ] }, { "output_type": "stream", "stream": "stdout", "text": [ " {'extended': '', 'description': 'Educator Introduction to C++ with Alvin Sylvain', 'tags': 'programming', 'url': 'http://tutolearning.com/educator-introduction-to-c-with-alvin-sylvain/', 'user': '', 'dt': ''}\n", "p1=" ] }, { "output_type": "stream", "stream": "stdout", "text": [ " {'extended': '', 'description': 'Code Snippets - Snipplr Social Snippet Repository', 'tags': 'code', 'url': 'http://snipplr.com/', 'user': 'willyfresh', 'dt': ''}\n", "p1=" ] }, { "output_type": "stream", "stream": "stdout", "text": [ " {'extended': '', 'description': 'How We Made GitHub Fast - GitHub', 'tags': 'github', 'url': 'https://github.com/blog/530-how-we-made-github-fast', 'user': '', 'dt': ''}\n", "262" ] }, { "output_type": "stream", "stream": "stdout", "text": [ " users\n" ] } ], "prompt_number": 28 }, { "cell_type": "code", "collapsed": false, "input": [ "print del_users.keys()[:50]\n", "[user for user in del_users.keys() if len(user)<3]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "['lorn', 'sibilsalim', 'pixelomatic', 'krapaille', 'todeqiralora', 'kucisaviwy', 'suntzu23', 'jizumabesyr', 'lokosozazuwa', 'clever.netman', 'anonymas', 'kojipyfex', 'arkitekt', 'chamerling', 'arozwalak', 'dyh1919', 'kostas345crew', 'paulokeeffe', 'lovrozitnik', 'msafty', 'jgradim', 'ole1981', 'fenng', 'rkg_mbp', 'forcemajor', 'tomohiro', 'codingeye', 'jpcochran', 'staii', 'gekacebene', 'luisrojascr', 'viktorium', 'bds023', 'wihatofoho', 'roshanbh', 'taluwacerij', 'elvencao', 'bd808', 'deja_rulez', 'igoritl', 'jmatraszek', 'alpsantos', 'mi2195', 'cyberlabe.fr', 'irc', 'salabuzot', 'gareth', 'jwolski', 't.chaffee', 'juanodicio']\n" ] }, { "output_type": "pyout", "prompt_number": 29, "text": [ "[]" ] } ], "prompt_number": 29 }, { "cell_type": "code", "collapsed": false, "input": [ "def fillItems(user_dict):\n", " all_items={}\n", " # Find links posted by all users initialized in user_dict\n", " for user in user_dict:\n", " if len(user)<2: continue #skip blank users\n", " for i in range(3):\n", " try:\n", " posts=get_userposts(user)\n", " break\n", " except:\n", " print \"Failed user \"+user+\", retrying\"\n", " time.sleep(4)\n", " for post in posts:\n", " url=post['url'].encode('ascii','ignore')\n", " user_dict[user][url]=1.0\n", " all_items[url]=1\n", " \n", " # Fill in missing items with 0\n", " for ratings in user_dict.values():\n", " for item in all_items:\n", " if item not in ratings:\n", " ratings[item]=0.0" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 30 }, { "cell_type": "code", "collapsed": false, "input": [ "fillItems(del_users)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 31 }, { "cell_type": "code", "collapsed": false, "input": [ "import random\n", "user=random.choice(del_users.keys())\n", "user" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 55, "text": [ "'frockenstein'" ] } ], "prompt_number": 55 }, { "cell_type": "code", "collapsed": false, "input": [ "#find users similar to that one\n", "topMatches(del_users,user)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 56, "text": [ "[('delbook', 0.102),\n", " ('ole1981', 0.096),\n", " ('mrragga', 0.096),\n", " ('hardcod3d', 0.096),\n", " ('ullu', -0.003)]" ] } ], "prompt_number": 56 }, { "cell_type": "code", "collapsed": false, "input": [ "#find recommended urls for that user\n", "#recommendation engine for del.icio.us\n", "#look for tags similar to one another\n", "#can also look for people trying to manipulate popular pages by posting same via multiple accounts\n", "#item based filtering\n", "getRecommendations(del_users,user)[:10]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 57, "text": [ "[('http://cloud.ubuntu.com/2010/11/using-ubuntu-images-on-aws-free-tier/',\n", " 0.262),\n", " ('http://blog.grayproductions.net/articles/load_an_ec2_gui_on_your_mac_os_x_box',\n", " 0.262),\n", " ('http://betterexplained.com/articles/how-to-optimize-your-site-with-http-caching/',\n", " 0.262),\n", " ('http://misoproject.com/dataset/examples/highstockandcsv.html', 0.262),\n", " ('http://twitter.github.com/bootstrap/', 0.262),\n", " ('http://flurdy.com/docs/ec2/ubuntu/', 0.262),\n", " ('http://michaelbushe.wordpress.com/', 0.262),\n", " ('http://fourkitchens.com/blog/2011/09/20/trigger-jenkins-builds-pushing-github',\n", " 0.262),\n", " ('http://www.gulli.com/news/kino-to-ra-christian-solmecke-sch-tzt-risiken-f-r-nutzer-ab-2011-06-08',\n", " 0.246),\n", " ('http://www.cmdbuild.org/en', 0.246)]" ] } ], "prompt_number": 57 }, { "cell_type": "code", "collapsed": false, "input": [ "url=getRecommendations(delusers,user)[0][0]\n", "print 'url=',url\n", "#url='http://ebookbrowse.com/'\n", "#find urls co-liked hence 'similar'\n", "topMatches(transformPrefs(delusers),url)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "http://thecleancoder.blogspot.com/2011/01/transformation-priority-and-sorting.html?m=1\n" ] }, { "output_type": "pyout", "prompt_number": 52, "text": [ "[(u'http://stackoverflow.com/questions/13132864/circular-tooltip/13137862#13137862',\n", " 1.0),\n", " (u'https://speakerdeck.com/arthurakay/end-to-end-unit-testing-for-web-developers',\n", " 1.0),\n", " (u'http://pastebin.com/3RSUzfDk', 1.0),\n", " (u'https://speakerdeck.com/arthurakay/your-code-sucks-best-practices-for-enterprise-javascript-development',\n", " 1.0),\n", " (u'http://sergeytihon.wordpress.com/2013/02/28/servicestack-new-api-f-sample-web-service-out-of-a-web-server/',\n", " 1.0)]" ] } ], "prompt_number": 52 }, { "cell_type": "code", "collapsed": false, "input": [ "#user based filtering can be slow, use item based collaborative filtering\n", "#precompute most similar for each item\n", "#then look at user's top rated items, and create weighted list of items most similar to those\n", "#based on precomputed similarities\n", "#(comparisons between items don't change as fast as new users added)\n", "def calculateSimilarItems(prefs,n=10):\n", " # Create a dictionary of items showing which other items they are most similar to.\n", " result={}\n", " # Invert the preference matrix to be item-centric\n", " itemPrefs=transformPrefs(prefs)\n", " c=0\n", " for item in itemPrefs:\n", " # Status updates for large datasets\n", " c+=1\n", " if c%100==0: print \"%d / %d\" % (c,len(itemPrefs))\n", " # Find the most similar items to this one\n", " scores=topMatches(itemPrefs,item,n=n,similarity=sim_distance)\n", " result[item]=scores\n", " return result" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 58 }, { "cell_type": "code", "collapsed": false, "input": [ "itemsim=calculateSimilarItems(critics)\n", "itemsim" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 59, "text": [ "{'Just My Luck': [('Lady in the Water', 0.222),\n", " ('You, Me and Dupree', 0.182),\n", " ('The Night Listener', 0.154),\n", " ('Snakes on a Plane', 0.105),\n", " ('Superman Returns', 0.065)],\n", " 'Lady in the Water': [('You, Me and Dupree', 0.4),\n", " ('The Night Listener', 0.286),\n", " ('Snakes on a Plane', 0.222),\n", " ('Just My Luck', 0.222),\n", " ('Superman Returns', 0.091)],\n", " 'Snakes on a Plane': [('Lady in the Water', 0.222),\n", " ('The Night Listener', 0.182),\n", " ('Superman Returns', 0.167),\n", " ('Just My Luck', 0.105),\n", " ('You, Me and Dupree', 0.051)],\n", " 'Superman Returns': [('Snakes on a Plane', 0.167),\n", " ('The Night Listener', 0.103),\n", " ('Lady in the Water', 0.091),\n", " ('Just My Luck', 0.065),\n", " ('You, Me and Dupree', 0.053)],\n", " 'The Night Listener': [('Lady in the Water', 0.286),\n", " ('Snakes on a Plane', 0.182),\n", " ('Just My Luck', 0.154),\n", " ('You, Me and Dupree', 0.148),\n", " ('Superman Returns', 0.103)],\n", " 'You, Me and Dupree': [('Lady in the Water', 0.4),\n", " ('Just My Luck', 0.182),\n", " ('The Night Listener', 0.148),\n", " ('Superman Returns', 0.053),\n", " ('Snakes on a Plane', 0.051)]}" ] } ], "prompt_number": 59 }, { "cell_type": "code", "collapsed": false, "input": [ "#this recommender now uses the precomputed item similarities\n", "def getRecommendedItems(prefs,itemMatch,user):\n", " userRatings=prefs[user]\n", " scores={}\n", " totalSim={}\n", " # Loop over items rated by this user\n", " for (item,rating) in userRatings.items( ):\n", "\n", " # Loop over items similar to this one\n", " for (item2,similarity) in itemMatch[item]:\n", " # Ignore if this user has already rated this item\n", " if item2 in userRatings: continue\n", " # Weighted sum of rating times similarity\n", " if item2 not in scores:\n", " scores[item2]=0\n", " totalSim[item2]=0\n", " scores[item2]+=similarity*rating\n", " # Sum of all the similarities\n", " totalSim[item2]+=similarity\n", "\n", " # Divide each total score by total weighting to get an average\n", " rankings=[(item,float(\"%.3f\"%(scores[item]/totalSim[item]))) for item in scores]\n", "\n", " return sorted(rankings,key=lambda x:x[1],reverse=True)" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 60 }, { "cell_type": "code", "collapsed": false, "input": [ "#works the same for constant set\n", "getRecommendedItems(critics,itemsim,'Toby')" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 61, "text": [ "[('The Night Listener', 3.185),\n", " ('Just My Luck', 2.598),\n", " ('Lady in the Water', 2.473)]" ] } ], "prompt_number": 61 }, { "cell_type": "code", "collapsed": false, "input": [ "#now get a real movie dataset from movielens, the smallest one\n", "#http://www.grouplens.org/node/12\n", "#http://www.grouplens.org/system/files/ml-100k.zip\n", "#contains\n", "#u.item list of movie ids and titles\n", "#u.data ratings user id, movie id, rating, timestamp\n", "#stored in ml-100k/ folder\n", "\n", "def loadMovieLens(path='ml-100k/'):\n", " # Get movie titles\n", " movies={}\n", " for line in open(path+'u.item'):\n", " (id,title)=line.split('|')[0:2]\n", " movies[id]=title\n", " \n", " # Load data\n", " prefs={}\n", " for line in open(path+'u.data'):\n", " (user,movieid,rating,ts)=line.split('\\t')\n", " if user not in prefs: prefs[user]={}\n", " prefs[user][movies[movieid]]=float(rating)\n", " return prefs" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 62 }, { "cell_type": "code", "collapsed": false, "input": [ "mprefs=loadMovieLens()" ], "language": "python", "metadata": {}, "outputs": [], "prompt_number": 63 }, { "cell_type": "code", "collapsed": false, "input": [ "len(mprefs),map(len,mprefs.values()[:10])" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 64, "text": [ "(943, [188, 230, 193, 198, 44, 20, 201, 236, 25, 21])" ] } ], "prompt_number": 64 }, { "cell_type": "code", "collapsed": false, "input": [ "topMatches(transformPrefs(mprefs),'Terminator, The (1984)',n=10)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 79, "text": [ "[('8 Seconds (1994)', 1.0),\n", " ('Calendar Girl (1993)', 1.0),\n", " ('Hurricane Streets (1998)', 1.0),\n", " (\"Ed's Next Move (1996)\", 1.0),\n", " ('Wild Reeds (1994)', 1.0),\n", " ('Scarlet Letter, The (1926)', 1.0),\n", " ('Vermin (1998)', 1.0),\n", " ('Outlaw, The (1943)', 1.0),\n", " ('Rhyme & Reason (1997)', 1.0),\n", " ('Beans of Egypt, Maine, The (1994)', 1.0)]" ] } ], "prompt_number": 79 }, { "cell_type": "code", "collapsed": false, "input": [ "#get recommendations for user 87\n", "getRecommendations(mprefs,'87')[:30]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 80, "text": [ "[('They Made Me a Criminal (1939)', 5.0),\n", " ('Santa with Muscles (1996)', 5.0),\n", " ('Saint of Fort Washington, The (1993)', 5.0),\n", " ('Entertaining Angels: The Dorothy Day Story (1996)', 5.0),\n", " ('Marlene Dietrich: Shadow and Light (1996) ', 5.0),\n", " ('Star Kid (1997)', 5.0),\n", " ('Great Day in Harlem, A (1994)', 5.0),\n", " ('Boys, Les (1997)', 5.0),\n", " ('Legal Deceit (1997)', 4.899),\n", " ('Letter From Death Row, A (1998)', 4.815),\n", " ('Hearts and Minds (1996)', 4.733),\n", " ('Pather Panchali (1955)', 4.697),\n", " ('Lamerica (1994)', 4.653),\n", " ('Leading Man, The (1996)', 4.54),\n", " ('Mrs. Dalloway (1997)', 4.535),\n", " ('Innocents, The (1961)', 4.532),\n", " ('Casablanca (1942)', 4.528),\n", " ('Everest (1998)', 4.51),\n", " ('Dangerous Beauty (1998)', 4.494),\n", " ('Wallace & Gromit: The Best of Aardman Animation (1996)', 4.485),\n", " ('Wrong Trousers, The (1993)', 4.463),\n", " ('Kaspar Hauser (1993)', 4.452),\n", " ('Usual Suspects, The (1995)', 4.431),\n", " ('Maya Lin: A Strong Clear Vision (1994)', 4.429),\n", " ('Wedding Gift, The (1994)', 4.416),\n", " ('Affair to Remember, An (1957)', 4.378),\n", " ('Anna (1996)', 4.376),\n", " ('As Good As It Gets (1997)', 4.376),\n", " ('Good Will Hunting (1997)', 4.376),\n", " ('Close Shave, A (1995)', 4.368)]" ] } ], "prompt_number": 80 }, { "cell_type": "code", "collapsed": false, "input": [ "#now item based\n", "itemsim=calculateSimilarItems(mprefs,n=50)" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "stream", "stream": "stdout", "text": [ "100 / 1664\n", "200 / 1664" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n", "300 / 1664" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n", "400 / 1664" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n", "500 / 1664" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n", "600 / 1664" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n", "700 / 1664" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n", "800 / 1664" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n", "900 / 1664" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n", "1000 / 1664" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n", "1100 / 1664" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n", "1200 / 1664" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n", "1300 / 1664" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n", "1400 / 1664" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n", "1500 / 1664" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n", "1600 / 1664" ] }, { "output_type": "stream", "stream": "stdout", "text": [ "\n" ] } ], "prompt_number": 81 }, { "cell_type": "code", "collapsed": false, "input": [ "#takes a while to build, but now recommendations instantaneous, and indep\n", "# of number of users. experiment with this dataset...\n", "getRecommendedItems(mprefs,itemsim,'189')[:30]" ], "language": "python", "metadata": {}, "outputs": [ { "output_type": "pyout", "prompt_number": 85, "text": [ "[('B. Monkey (1998)', 5.0),\n", " ('Down Periscope (1996)', 5.0),\n", " ('Crude Oasis, The (1995)', 5.0),\n", " ('Rent-a-Kid (1995)', 5.0),\n", " ('House Party 3 (1994)', 5.0),\n", " ('Leading Man, The (1996)', 5.0),\n", " ('Mallrats (1995)', 5.0),\n", " ('How to Be a Player (1997)', 5.0),\n", " ('Party Girl (1995)', 5.0),\n", " ('Sneakers (1992)', 5.0),\n", " ('Philadelphia Story, The (1940)', 5.0),\n", " ('Swiss Family Robinson (1960)', 5.0),\n", " ('Gigi (1958)', 5.0),\n", " ('Love! Valour! Compassion! (1997)', 5.0),\n", " ('Treasure of the Sierra Madre, The (1948)', 5.0),\n", " ('Police Story 4: Project S (Chao ji ji hua) (1993)', 5.0),\n", " ('Curdled (1996)', 5.0),\n", " ('B*A*P*S (1997)', 5.0),\n", " ('Mimic (1997)', 5.0),\n", " ('Prophecy, The (1995)', 5.0),\n", " ('Stranger in the House (1997)', 5.0),\n", " ('Dead Presidents (1995)', 5.0),\n", " ('Man of the House (1995)', 5.0),\n", " ('Power 98 (1995)', 5.0),\n", " ('Renaissance Man (1994)', 5.0),\n", " ('Coldblooded (1995)', 5.0),\n", " ('Killer (Bulletproof Heart) (1994)', 5.0),\n", " (\"Wes Craven's New Nightmare (1994)\", 5.0),\n", " ('Original Gangstas (1996)', 5.0),\n", " (\"Marvin's Room (1996)\", 5.0)]" ] } ], "prompt_number": 85 }, { "cell_type": "code", "collapsed": false, "input": [], "language": "python", "metadata": {}, "outputs": [] } ], "metadata": {} } ] }