| |
| import datetime |
| from operator import itemgetter, attrgetter |
| |
| # can get sample data here: |
| # wget http://www.grouplens.org/system/files/ml-100k.zip |
| # app data file config |
| APPDATA_DIRNAME = "ml-100k" |
| USERS_FILENAME = "u.user" |
| USERS_FILE_DELIMITER = "|" |
| ITEMS_FILENAME = "u.item" |
| ITEMS_FILE_DELIMITER = "|" |
| RATE_ACTIONS_FILENAME = "u.data" |
| RATE_ACTIONS_DELIMITER = "\t" |
| |
| |
| class User: |
| def __init__(self, uid): |
| self.uid = uid |
| self.rec = [] # recommendations, list of iid |
| |
| def __str__(self): |
| return "User[uid=%s,rec=%s]" % (self.uid, self.rec) |
| |
| class Item: |
| def __init__(self, iid, name): |
| self.iid = iid |
| self.name = name |
| |
| def __str__(self): |
| return "Item[iid=%s,name=%s]" % (self.iid, self.name) |
| |
| class RateAction: |
| def __init__(self, uid, iid, rating, t): |
| self.uid = uid |
| self.iid = iid |
| self.rating = rating |
| self.t = t |
| |
| def __str__(self): |
| return "RateAction[uid=%s,iid=%s,rating=%s,t=%s]" % (self.uid, self.iid, self.rating, self.t) |
| |
| |
| class AppData: |
| |
| def __init__(self): |
| self._users = {} # dict of User obj |
| self._items = {} # dict of Item obj |
| self._rate_actions = [] # list of RateAction obj |
| |
| self._users_file = "%s/%s" % (APPDATA_DIRNAME, USERS_FILENAME) |
| self._items_file = "%s/%s" % (APPDATA_DIRNAME, ITEMS_FILENAME) |
| self._rate_actions_file = "%s/%s" % (APPDATA_DIRNAME, RATE_ACTIONS_FILENAME) |
| self.__init_users() |
| self.__init_items() |
| self.__init_rate_actions() |
| |
| def __init_users(self): |
| """ |
| uid| |
| """ |
| print "[Info] Initializing users..." |
| f = open(self._users_file, 'r') |
| for line in f: |
| data = line.rstrip('\r\n').split(USERS_FILE_DELIMITER) |
| self.add_user(User(data[0])) |
| f.close() |
| print "[Info] %s users were initialized." % len(self._users) |
| |
| def __init_items(self): |
| """ |
| iid|name |
| """ |
| print "[Info] Initializing items..." |
| f = open(self._items_file, 'r') |
| for line in f: |
| data = line.rstrip('\r\n').split(ITEMS_FILE_DELIMITER) |
| self.add_item(Item(data[0], data[1])) |
| f.close() |
| print "[Info] %s items were initialized." % len(self._items) |
| |
| def __init_rate_actions(self): |
| """ |
| uid|iid|rating|timestamp |
| """ |
| print "[Info] Initializing rate actions..." |
| f = open(self._rate_actions_file, 'r') |
| for line in f: |
| data = line.rstrip('\r\n').split(RATE_ACTIONS_DELIMITER) |
| t = datetime.datetime.utcfromtimestamp(int(data[3])).isoformat() |
| self.add_rate_action(RateAction(data[0], data[1], data[2], t)) |
| f.close() |
| print "[Info] %s rate actions were initialized." % len(self._rate_actions) |
| |
| def add_user(self, user): |
| self._users[user.uid] = user |
| |
| def add_item(self, item): |
| self._items[item.iid] = item |
| |
| def add_rate_action(self, action): |
| self._rate_actions.append(action) |
| |
| def get_users(self): |
| return self._users |
| |
| def get_items(self): |
| return self._items |
| |
| def get_rate_actions(self): |
| return self._rate_actions |
| |
| def get_user(self, uid): |
| """return single user |
| """ |
| if uid in self._users: |
| return self._users[uid] |
| else: |
| return None |
| |
| def get_item(self, iid): |
| """return single item |
| """ |
| if iid in self._items: |
| return self._items[iid] |
| else: |
| return None |
| |
| def get_top_rated_items(self, uid, n): |
| """get top n rated iids by this uid |
| """ |
| if uid in self._users: |
| actions = filter(lambda u: u.uid==uid, self._rate_actions) |
| top = sorted(actions, key=attrgetter('rating'), reverse=True) |
| topn_iids = map(lambda a: a.iid, top[:n]) |
| return topn_iids |
| else: |
| return None |
| |
| def get_top_rate_actions(self, uid, n): |
| """get top n rated actions by this uid |
| """ |
| if uid in self._users: |
| actions = filter(lambda u: u.uid==uid, self._rate_actions) |
| top = sorted(actions, key=attrgetter('rating'), reverse=True) |
| return top[:n] |
| else: |
| return None |