【RecSys】Slope One算法
25 Jan 2014Slope One 算法是由 Daniel Lemire 教授在 2005 年提出的一个 Item-Based 推荐算法。
Slope One 算法试图同时满足这样的的 5 个目标:
易于实现和维护:普通工程师可以轻松解释所有的聚合数据,并且算法易于实现和测试。
运行时可更新的:新增一个评分项,应该对预测结果即时产生影响。
高效率的查询响应:快速的执行查询,可能需要付出更多的空间占用作为代价。
对初次访问者要求少:对于一个评分项目很少的用户,也应该可以获得有效的推荐。
合理的准确性:与最准确的方法相比,此方法应该是有竞争力的,准确性方面的微小增长不能以简单性和扩展性的大量牺牲为代价。
举例:
User A 给 Item I 打分为 1;给 Item J 打分为 1.5。
Uesr B 给 Item I 打分为 2。
问题是:User B 给 Item J 打分为多少?
使用 Slope One 算法,答案是:2.5,2+(1.5-1)=2.5。
python实现的简易slopeone算法:
class SlopeOne(object): def __init__(self): self.diffs = {} self.freqs = {} def predict(self, userprefs): preds, freqs = {}, {} for item, rating in userprefs.iteritems(): for diffitem, diffratings in self.diffs.iteritems(): try: freq = self.freqs[diffitem][item] except KeyError: continue preds.setdefault(diffitem, 0.0) freqs.setdefault(diffitem, 0) preds[diffitem] += freq * (diffratings[item] + rating) freqs[diffitem] += freq return dict([(item, value / freqs[item]) for item, value in preds.iteritems() if item not in userprefs and freqs[item] > 0]) def update(self, userdata): for ratings in userdata.itervalues(): for item1, rating1 in ratings.iteritems(): self.freqs.setdefault(item1, {}) self.diffs.setdefault(item1, {}) for item2, rating2 in ratings.iteritems(): self.freqs[item1].setdefault(item2, 0) self.diffs[item1].setdefault(item2, 0.0) self.freqs[item1][item2] += 1 self.diffs[item1][item2] += rating1 - rating2 for item1, ratings in self.diffs.iteritems(): for item2 in ratings: ratings[item2] /= self.freqs[item1][item2] if __name__ == '__main__': userdata = dict( alice=dict(squid=1.0, cuttlefish=0.5, octopus=0.2), bob=dict(squid=1.0, octopus=0.5, nautilus=0.2), carole=dict(squid=0.2, octopus=1.0, cuttlefish=0.4, nautilus=0.4), dave=dict(cuttlefish=0.9, octopus=0.4, nautilus=0.5), ) s = SlopeOne() s.update(userdata) print s.predict(dict(squid=0.4))
转载请注明:于哲的博客 » 【RecSys】Slope One算法