随笔

import math
import operator


# 1.获取用户与用户之间的相似度
# 1.1 正常逻辑的用户相似度计算


def user_similarity(train):
w = dict()
for u in train.keys():
for v in train.keys():
if u == v:
continue
w[u][v] = len(train[u] & train[v])
w[u][v] /= math.sqrt(len(train[u]) * len(train[v]) * 1.0)
return w


# 1.2优化计算用户与用户相似度


def simple_user_similarity(train):
# 建立item->users倒排表
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)

# 计算用户共同items的数量
C = dict() # 存放统计用户与用户共同item数量
N = dict() # 存放用户对应的item数量
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.3 在原有计算优化上,增加用户体验上的优化点,对用户u和用户v共同的热门物品进行惩罚
# 1/log(1+物品热度【拥有用户数量】)


def user_iif_sim(train):
# item->users倒排
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)
# 计算相似user共同的物品数量,+热门物品衰减
C = dict()
N = dict()
for i, users in item_users.items():
for u in users:
if N.get(u,-1)==-1:
N[u]=0
N[u] += 1 # 存储用户拥有的items
if C.get(u,-1)==-1:
C[u] = dict()
for v in users:
if u == v: # 过滤掉对同一用户的再次计算
continue
elif C[u].get(v,-1)==-1:
C[u][v]=0
C[u][v] += 1 / math.log(1 + len(users))
# 计算最终的相似度矩阵
W = dict()
for u,related_users in C.items():
if W.get(u,-1)==-1:
W[u]=dict()
for v, cuv in related_users.items():
if W[u].get(v,-1)==-1:
W[u][v]=0
W[u][v] = cuv / math.sqrt(N[u]*N[v])
return W


# 2. 用户U对物品i的感兴趣程度(score)


def recommend(user, train, w, k):
rank = dict()
interacted_items = train[user].keys()
for v, wuv in sorted(w[user].items(),
key=operator.itemgetter(1),
reverse=True)[0:k]:
for i, rvi in train[v].items():
if i in interacted_items:
# 过滤用户已经看过的
continue
elif rank.get(i,-1)==-1:
rank[i]=0
rank[i] += wuv * rvi
return rank

原文地址:https://www.cnblogs.com/xiaozhican/p/13702513.html