用户相似度计算的改进
Poblog 07月30日 2017
Random 算法每次都随机挑选 10 个用户没有产生过行为的物品推荐给当前用户
MostPopular 算法则按照物品的流行度给用户推荐他没有产生过行为的物品中最热门的 10 个物品
UserCF 的准确率和召回率相对 MostPopular 算法提高了将近 1 倍。同时,UserCF 的覆盖率远远高于 MostPopular ,推荐结果相对 MostPopular 不太热门
准确率和召回率: K=80 左右会获得比较高的准确率和召回率
覆盖率:K 越大则 UserCF 推荐结果的覆盖率越低。覆盖率的降低是因为流行度的增加,随着流行度增加, UserCF 越来越倾向于推荐热门的物品,从而对长尾物品的推荐越来越少,因此造成了覆盖率的降低
流行度: K 越大则 UserCF 推荐结果就越热门
用户相似度计算的改进
原理:两个用户对冷门物品采取过同样的行为更能说明他们兴趣的相似度
代码对应(和I只有一处差别):
def UserSimilarity(train):
//train:{'196': {'242': 1.0,'241': 1.0},
'198': {'243': 1.0,'246': 1.0}
....} 训练集字典 对应W(A,a)
//
# build inverse table for item_users
item_users = dict()
for u,items in train.items():
//u:'196'
items:{'242': 1.0,....}
//
for i in items.keys():
//i:'242'
//
if i not in item_users:
item_users[i] = set()
item_users[i].add(u)
//item_users:{'242': {'196'}}
//
//用户物品倒排表:
item_users:{'242': {'196'...},
....}
//
#calculate co-rated items between users
C = dict()
N = dict()
for i,users in item_users.items():
//i:'242'
users:{'196', '463', '568', ...}
//
for u in users:
//u:'196'
//
N.setdefault(u,0)
//N:{'196': 0}
//
N[u] += 1
//N:{'196': 1}
//
C.setdefault(u,{})
//C:{'196': {}}
//
for v in users:
//v:'196'
//
if u == v:
continue
C[u].setdefault(v,0)
//C:{'196': {'463': 0}}
//
C[u][v] += 1 / math.log(1+len(users))
//这里是和I不一样的计算位置,该公式惩罚了用户 u 和用户 v 共同兴趣列表中热门物品对他们相似度的影响
I的写法为 C[u][v] += 1
//
#calculate finial similarity matrix W
W = C.copy()
for u, related_users in C.items():
//u:'753'
related_users:{'624': 9, '724': 9, ....}
//
for v, cuv in related_users.items():
//v:'624'
cuv:9
//
W[u][v] = cuv / math.sqrt(N[u] * N[v])
//W:{'753': {'624': 0.13301622404223282, '724': 0.16598500055174645,...}
....}
'753'和'624'的相似度是0.13301622404223282
//
return W
实际在线系统使用UserCF的例子
UserCF 在目前的实际应用中使用并不多
Digg 在博客中公布了使用推荐系统后的效果,主要指标如下所示
用户反馈增加:用户“顶”和“踩”的行为增加了 40%
平均每个用户将从 34 个具相似兴趣的好友那儿获得 200 条推荐结果
用户和好友的交互活跃度增加了24%
用户评论增加了 11%