# coding=utf-8
# @Time : 2019/12/4 20:21
# @Author : Z
# @Email : S
# @File : UserBasedCF.py
#MovieLens电影推荐系统
import math
#定义基于用户得协同过滤算法类
class UserBasedCF:
#初始化对象
def __init__(self,train_file,test_file):
#训练数据
self.train_file=train_file
#测试数据
self.test_file=test_file
#读取数据
self.readData()
#数据读取函数
def readData(self):
#读取文件,生成用户-物品的评分表和测试集
#用户-物品的评分表
#训练集
#dict()函数用于创建一个字典。
self.train=dict()
#打开文件,按行读取训练数据
for line in open(self.train_file):
#获得用户‘物品、评分数据,丢弃时间戳数据
user,item,score,_ = line.strip().split("\t")
#用户-物品评分矩阵
self.train.setdefault(user,{})
#分数赋值
self.train[user][item]=int(score)
#print(self.train[user][item])
#测试集
self.test=dict()
#打开文件,按行读取训练数据
for line in open(self.test_file):
# 获得用户‘物品、评分数据,丢弃时间戳数据
user,item,score,_ = line.strip().split("\t")
# 用户-物品评分矩阵
self.test.setdefault(user, {})
# 分数赋值
self.test[user][item] = int(score)
#用户间相似度
def UserSimilarity(self):
#建立物品-用户的倒排表
#数据格式:key:物品 value:用户1,用户2
self.item_users=dict()
#遍历训练集中用户-物品数据
for user,items in self.train.items():
#遍历用户对应的物品数据
for i in items.keys():
#倒排表还没有该物品
if i not in self.item_users:
#倒排表中该物品项赋值为set()集合
self.item_users[i]=set()
#倒排表中该物品项添加该用户
self.item_users[i].add(user)
#计算用户-用户相关性矩阵
C=dict() #用户-用户共现矩阵
N=dict() #用户产生行为的物品个数
#遍历物品-用户的倒排表,取得物品-用户数据
for i,users in self.item_users.items():
#遍历物品i下的用户
for u in users:
#初始化用户产生行为的物品个数0
N.setdefault(u,0)
#遍历到该用户加1
N[u] += 1
#用户-用户共现矩阵初始化
C.setdefault(u,{})
#遍历该物品下的所有用户
for v in users:
#若该项为当前用户,跳过
if u == v:
continue
#遍历到其他不同用户则加1
#初始化为0
C[u].setdefault(v,0)
#加1
C[u][v] += 1
#计算用户-用户相似度,余弦相似度
self.W = dict() #相似度矩阵
#遍历用户-用户共现矩阵的所有项
#每行用户、该行下的其他用户
for u,related_users in C.items():
#存放用户间相似度
self.W.setdefault(u,{})
#遍历其他每一个用户及对应的同现矩阵的值,即分子部分
for v,cuv in related_users.items():
#余弦相似度
self.W[u][v] = cuv / math.sqrt(N[u] * N[v])
#返回用户相似度
return self.W
#给用户user推荐,前K个相关用户喜欢的
#用户user未产生过行为的物品
#默认3个用户,推荐10个物品
def Recommend(self,user,K=3,N=10):
#用户user对物品的偏好值
rank=dict()
#用户user产生过行为的物品项item
action_item=self.train[user].keys()
#对用户user按相似度从大到小进行排列
#取与用户user相似度最大的K个用户
for v,wuv in sorted(self.W[user].items(),key=lambda x: x[1],reverse=True)[0:K]:
#遍历前K个与user最相关的用户
#遍历每件物品、用户对该物品的偏好值
for i,rvi in self.train[v].items():
#若用户user对物品i已有评价,则跳过
if i in action_item:
continue
#计算用户user对物品i的偏好值
#初始化该值为0
rank.setdefault(i,0)
#通过与其相似用户对物品i的偏好值相乘并相加
rank[i]+=wuv * rvi
#按评分值大小,为用户user推荐结果的取前N个物品
return dict(sorted(rank.items(),key=lambda x: x[1],reverse=True)[0:N])
if __name__ == '__main__':
#将训练集和测试集指定为u.data
cf=UserBasedCF('u.data','u.data')
cf.UserSimilarity()
#找出和用户3最相近用户的十个商品以及相似度
print(cf.Recommend('3'))
# {'313': 7.702489204665911, '301': 5.134562597476054, '315': 6.675060438409236, '895': 6.156249766438661,
# '292': 4.627235120093614, '269': 5.140304194770122, '286': 7.193871110379812, '289': 5.65337326944663,
# '316': 6.675060438409236, '750': 6.172183941417205}
MovieLens movie recommendation system
Guess you like
Origin blog.csdn.net/NewBeeMu/article/details/103403765
Recommended
Ranking