2014-03-26
基于用户的协同过滤,英文是user-based collaborative filter
,简称User CF
。下面直接尝试使用该方法做图书推荐。
判断用户之间的相似性
假定有用户user1、user2和user3,三人都读过图书book01、book02、book03、book04。三个用户对四本书的评价依次是:
用户 | book01 | book02 | book03 | book04 |
---|---|---|---|---|
user1 | 2 | 4.5 | 4.5 | 3 |
user2 | 2.5 | 4.0 | 4.5 | 3 |
user3 | 4 | 3 | 3 | 4 |
使用欧几里得距离判断三个用户之间的相似性:
from math import sqrt
def get_euclidean_similarity(dot1, dot2):
''' 根据欧几里得距离判断相似性'''
s = sum([pow(dot1[x] - dot2[x], 2) for x in range(len(dot1))])
return 1.0 / (1.0 + sqrt(s))
if __name__ == '__main__':
user1 = [2, 4.5, 4.5, 3]
user2 = [2.5, 4.0, 4.5, 3]
user3 = [4, 3, 3, 4]
print get_euclidean_similarity(user1, user2)
print get_euclidean_similarity(user1, user3)
print get_euclidean_similarity(user2, user3)
结果如下:
user1~user2 | user1~user3 | user2~user3 |
---|---|---|
0.585786437627 | 0.244965529586 | 0.28172904669 |
可见user1和user2最为相似。
为用户推荐图书
假定user1面前有book11、book12、book13三本从未读过的书,如果user2和user3对这三本书的评分如下:
用户 | book11 | book12 | book13 |
---|---|---|---|
user2 | 3 | 4 | 4 |
user3 | 4 | 2 | 没读过 |
那么我们更推荐user1读那些书呢?这里可以考虑使用加权平均值(见资料[1])来为每本书计算一个值来表示对书的推荐程度:数值是对数的评分,权重是其他用户与user1的相似度。
于是,book11的推荐值为:
( simlarity(user1,user2)*evaluate(user2,book11) +
simlarity(user1,user3)*evaluate(user3,book11)
)
/
( simlarity(user1,user2)+simlarity(user1,user3) )
book12的推荐值与上类似。 由于user3没读过book13,所以book12的推荐值如下:
( simlarity(user1,user2)*evaluate(user2,book13) ) / simlarity(user1,user2)
最终结果是:
图书 | 推荐值 |
---|---|
book11 | 3.2948720427443683 |
book12 | 3.410255914511263 |
book13 | 4 |
book13的推荐值最大,所以应该向user1推荐book13。当然了,如果在实际生活中数据量很大的情况下,book13只有一个人评分,向user1推荐则是不合理的。
资料
[1] 加权平均值