-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathrw_reco.py
115 lines (96 loc) · 3.5 KB
/
rw_reco.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
from __future__ import division
import csv
import numpy as np
import math
import random
import operator
import itertools
import pickle
import json
import sys
# THIS RECEIVES
num_users = int(sys.argv[1:][0])
num_recs = int(sys.argv[1:][1])
BETA = float(sys.argv[1:][2])
WALKS = int(sys.argv[1:][3])
#BETA = 0.85
#WALKS = 1000
DUMP = 1
print "Loading Data..."
with open('f_all_users.json', 'r') as f:
all_users = json.load(f)
with open('f_item_names.json', 'r') as f:
item_names = json.load(f)
with open('f_item_averages.json', 'r') as f:
item_averages = json.load(f)
with open('f_item_edges.json', 'r') as f:
item_edges = json.load(f)
with open('f_user_edges.json', 'r') as f:
user_edges = json.load(f)
with open('items_liked_by_user.json', 'r') as f:
items_liked_by_user = json.load(f)
with open('items_disliked_by_user.json', 'r') as f:
items_disliked_by_user = json.load(f)
print "Done!"
def compute_user_to_item_edge_score(rating,item_average):
return 0.5*rating + 0.5*item_average
def compute_item_to_user_edge_score(rating,item_average):
return rating
def recommend(user,BETA,WALKS):
recommendations = {}
original_user = user
if not user in user_edges:
return recommendations
already_ranked = [str(x[0]) for x in user_edges[original_user]]
for i in xrange(WALKS):
if random.random()>=BETA:
user = original_user
if user in user_edges:
edges = user_edges[user]
# Substract averages and keep only positive items (for the user)
#edges = [(str(x[0]),compute_user_to_item(float(x[1]),item_averages[str(x[0])]) for x in edges if float(x[1])-(item_averages[str(x[0])])]
edges = [(str(x[0]),compute_user_to_item_edge_score(float(x[1]),item_averages[str(x[0])])) for x in edges]
# Convert to a list of items and weights
[items,weights] = zip(*edges)
# Convert weights to probabilities
total_weight = np.sum(weights)
probs = [p/total_weight for p in weights]
item = np.random.choice(items,size=1,replace=True,p=probs)
#theweight =item[1]
item = item[0]
if item not in already_ranked:
#print "selected: ",item_names[item]," ",item
if item not in recommendations:
recommendations[item]=0
recommendations[item]+=1
if item in item_edges:
edges = item_edges[item]
# Substract averages and keep only positive items (for the user)
edges = [(str(x[0]),compute_item_to_user_edge_score(float(x[1]),item_averages[item])) for x in edges]
# Convert to a list of items and weights
[users,weights] = zip(*edges)
# Convert weights to probabilities
total_weight = np.sum(weights)
probs = [p/total_weight for p in weights]
user = np.random.choice(users,size=1,replace=False,p=probs)
user = user[0]
sorted_items = sorted(recommendations.items(), key=operator.itemgetter(1), reverse=True)
return sorted_items
users_to_recommend = np.random.choice(all_users,num_users)
for user in users_to_recommend:
user = str(user)
if user in items_liked_by_user:
good_items = items_liked_by_user[user]
print "recommending for user:",user
liked_names = ",".join([item_names[str(item)] for item in good_items])
print "***** The User Likes:",liked_names
if user in items_disliked_by_user:
bad_items = items_disliked_by_user[user]
unliked_names = ",".join([item_names[str(item)] for item in bad_items])
print "* The User Dislikes:",unliked_names
recommended_items = recommend(user,BETA,WALKS)
print "We recommend:"
for item in recommended_items[0:num_recs]:
name = item_names[str(item[0])]
print item[0],name,item[1]
print "----------------------"