基于用户的协同过滤算法
2019-04-26 本文已影响0人
不要重不要重
看项亮的《推荐算法》记录如下,这是我看过最最最好理解的书:
- UserCF
item_users = dict()
for u, items in train.items():
for i in items.keys():
if i not in item_users:
item_users[i] = set()
item_users[i].add(u)
C = dict()
N = dict()
for i, users in item_users.items():
for u in users:
N[u] += 1
for v in users:
if u == v:
continue
C[u][v] += 1
W = dict()
for u, related_users in C.items():
for v, cuv in related_users.items():
W[u][v] = cuv / math.sqrt(N[u] * N[v])
return W
(1).第一部分形成物品到用户的倒排表,索引为物品id ,指向-->所有产生过正向行为的用户id
(2).从倒排表形成 二维数组,c[用户idA][用户idB]= A和B产生过正向行为的物品的交集数量
(3).计算用户之间的相似度(余弦相似度公式)
- User-IIF UserCF的改进
只有上面第二部分有改动
for i, users in item_users.items():
for u in users:
N[u] += 1
for v in users:
if u == v:
continue
C[u][v] += 1 / math.log(1 + len(users))
可见只有 在用户的交集上有变化,不再是单纯的加1,而是加该物品的权重,以减少流行或热数据对于最后结果的影响
- UserCF 推荐算法
def Recommend(user, train, W):
rank = dict()
interacted_items = train[user] #该用户已经产生过的数据
for v, wuv in sorted(W[u].items, key=itemgetter(1), \
reverse=True)[0:K]:
for i, rvi in train[v].items:
if i in interacted_items:
#we should filter items user interacted before
continue
rank[i] += wuv * rvi
return rank
对上述产生的用户相似度矩阵中关于 user 的列排序,找到前K个,然后把该K个用户的数据中产生过的物品 筛掉 本user产生过的物品,并计算出筛选后的数据的可推荐概率,最后返回该矩阵,调用者可以按需取需top n