基于Python的用户协同过滤推荐系统的研究与实现
2020-12-28秦育华
秦育华
摘要:推荐系统可以有效地帮助用户从海量信息中获得自己的潜在需求,为用户实现个性化推荐。本文研究了协同过滤算法,使用Python语言实现了基于用户的协同过滤推荐系统,构建了推荐系统的架构,给出了实现个性化推荐的关键代码,并在ml-latest-small 数据集上对用户相似度算法进行了测试。
关键词:相似性;协同过滤;推荐系统;Python
中图分类号:TP311 文献标识码:A
文章编号:1009-3044(2020)31-0234-03
1 概述
信息技术和互联网技术的迅猛发展以及数据量爆炸式的增长,将我们带到了“信息过载”[1]的时代,使我们难以从海量的数据中获得真正需要的信息。如何从海量信息中找到用户真正感兴趣的信息成为新的难题。传统搜索引擎主要依赖于用户对需求的准确描述,向所有用户提供相同的推荐结果,不是个性化服务。推荐系统不需要用户提供明确的需求,它通过分析用户的历史行为,挖掘用户兴趣并建模,主动为用户推荐能够满足他们兴趣和需要的信息[2],能够有效地为用户提供个性化服务。
2 推荐系统与相关技术
2.1推荐系统和协同过滤算法
推荐系统能够在信息过载的环境中,为用户精确的推荐令他们感兴趣的信息。它不仅能够满足用户的个性化需求,而且能够增强用户关联性[3],跟踪用户偏好,提高销售能力。推荐系统通常分为三类:基于内容的过滤、协同过滤和混合推荐。其中,协同过滤独立于资源,且不考虑物品内容信息,易于实现,是目前最成功且应用最广的一种推荐算法。
协同过滤算法(Collaborative Filtering,CF)是根据用户的历史行为信息,计算用户之间的相似度,并推荐用户喜欢的物品。协同过滤算法是根据用户的相似度,而不是物品的客观属性提供个性化的推荐,因此它可以过滤任何类型的物品,如电影、音乐、文本等。根据推荐对象的不同,协同过滤算法分为基于物品的协同过滤算法和基于用户的协同过滤算法。
2.2基于物品的协同过滤算法
基于物品的協同过滤算法(Item-based collaborative filtering ,Item-base CF)主要考虑用户的个性化特征,通过分析用户的行为数据,计算与用户喜欢的物品之间的相似度,为用户推荐与其之前感兴趣物品相似的新物品。该算法主要包括两个步骤:(1)根据用户的评分数据,计算任意两个物品之间的相似度;(2)根据物品间的相似度和用户的历史行为,为用户生成推荐物品列表。
2.3 基于用户的协同过滤算法
基于用户的协同过滤算法(User-based collaborative filtering, User-base CF)由Goldberg等人于1992年提出并用于邮件过滤系统[4]。该算法主要考虑用户的社会属性,通过分析用户的行为数据,计算用户之间的兴趣相似度,为目标用户推荐相似用户感兴趣的物品。该算法主要包括两个步骤:(1)找到与目标用户兴趣相似的用户集合;(2)在这个用户集合中,找到用户感兴趣的,且目标用户不知道的物品并推荐给目标用户。
3 基于用户的协同过滤推荐系统的设计与实现
3.1 用户相似度算法
相似度的度量在协同过滤中起着基础性的作用,如何计算用户之间的相似度,是协同过滤中最关键的问题。常见的计算用户相似度的算法有余弦相似度和欧氏距离等。
1)余弦相似度(Cosine Similarity)
在协同过滤的计算中,余弦相似度将用户评分看作是n维空间上的向量,通过计算两个向量之间夹角的余弦值,度量两个用户间的相似性,其值域为[-1, 1]:1代表夹角为0°, 表示完全相似;-1代表夹角为180°, 表示完全不相似。计算用户U和用户V的相似度公式如下:
[wuv=|N(u)∩N(v)||N(u)∥N(v)|]
其中,N(u)和N(V)表示用户U和用户V感兴趣的物品评分。余弦相似度注重两个向量在方向上的差异,而不是距离或长度上的差异,能够较好地反映用户间共同的兴趣。
2)欧氏距离(Euclidean Distance)
欧氏距离衡量的是空间中两点之间的绝对距离,在协同过滤的计算中,欧氏距离是根据两个用户共同评过分的项目集,计算两个用户的相似度。欧氏距离值越小,两个用户相似度越大;欧氏距离值越大,两个用户相似度越小。计算用户U和用户V的相似度公式如下:
[ Eu,v=i=1n(ui-vi)2]
其中,[ui]和[vi]表示用户U和用户V在共同评分的项目集中对物品的评分。当数据很稠密并且连续时,欧氏距离是很好的相似度计算方式。
3.2 推荐系统结构图
基于用户的协同过滤推荐算法,依据用户和物品的特征构建用户和物品的同现矩阵;然后根据用户的行为数据,计算用户之间的相似度,得到相似用户集合;最后采用协同过滤算法,给目标用户推荐相似用户喜欢而其不知道的物品。主要流程如图1所示,主要包括以下5个模块:
(1)数据预处理模块:提取物品特征和用户行为数据。
(2)构建用户字典模块:用字典表示每位用户评论的电影和评分。
(3)余弦相似度:根据用户字典模块中的评分,计算用户间的余弦相似度,生成该用户的相似度集合。
(4)欧氏相似度:根据(3)中计算的该用户相似度集合,计算该用户的欧氏相似度。
(5)推荐模块:根据计算的用户相似度,给相似用户按评分降序推荐N个物品。
4 推荐系统实现
4.1 数据集简介
本文试验采用ml-latest-small数据集[5],该数据集中有610个用户和9742部电影,包含了100836个收视率和3683个标签应用,产生100837条评分记录,每一条记录的评分为0.5-5的数字。
该数据集中的用户均为随机选择,每个用户不包含个人信息,所有被选中的用户至少对20部电影进行了评分。数据集收集的日期从1996年3月29日至2018年9月24日期间,于2018年9月26日创建。表1展示了评分数据集中2个评分记录的例子,包括用户ID、物品ID、评分和时间戳。表2展示了电影数据集中2个电影信息的例子,包括物品ID、电影名和电影类型。
4.2 数据预处理
提取数据集中的数据进行预处理,将电影信息数据集中的电影ID、电影名称和电影评分数据集中的用户ID和用户评分依次读出,建立物品和评分特征矩阵。其Python实现关键代码[6]如下:
defReadData(movie,rating):
'''
提取数据,并建立物品和评分特征矩阵
:param movies:表示电影信息数据集文件
:param ratings:表示电影评分数据集文件
:return:返回特征矩阵,并按userId的值排序
'''
movies=pd.read_csv(movie)
ratings=pd.read_csv(rating)
merge_data=pd.merge(ratings,movies,on='movieId')
merge_data.sort_values('userId')
returnmerge_data
4.3 用python构建用户字典
根据物品和评分矩阵,将每位用户评论的电影和评分存放在字典中。评分数据用于计算用户相似度,电影信息用于生成推荐结果。其Python实现关键代码如下:
defcreat_dict(file):
'''
:param file: 表示由特征矩阵生成的文件
:return: 返回结果是由字典存放每位用户评论的电影和评分
'''
data_dict={}
for line infile.readlines():
line=line.strip().split(',')
if not line[0] indata_dict.keys():
data_dict[line[0]]={line[3]:line[1]}
else:
data_dict[line[0]][line[3]]=line[1]
returndata_dict
4.4 相似度研究
1)用余弦相似度算法寻找相似用户
从用户字典中取出两个用户共同评分的电影,采用余弦相似度公式,计算两个用户间的相似度。其Python实现关键代码如下:
defcos_sim(user1,user2):
#根據两用户共同评分的电影,计算两者间的余弦相似度
user1_data=data_dict[user1]
user2_data=data_dict[user2]
common={}
forkeyin user1_data.keys():
ifkeyin user2_data .keys():
common[key]=1
iflen(common)==0:
return0
sum1Sq = sum([pow(float(user1_data[movie]),2) for movie in common])
sum2Sq = sum([pow(float(user2_data[movie]),2) for movie in common])
CSum=sum([float(user1_data[movie])*float(user2_data[movie]) for movie in common])
dist=sqrt(sum1Sq)*sqrt(sum2Sq)
ifden==0:
return 0
returnCSum/dist
2)用欧氏距离找出相似用户
从用户字典中取出两用户共同评分的电影,采用欧氏距离公式,计算两用户间的相似度。其Python实现关键代码如下:
defEuclid_sim(user1,user2):
#根据两用户共同评论过的电影,计算两者间的欧氏距离
user1_data=data_dict[user1]
user2_data=data_dict[user2]
distance=0
forkeyin user1_data.keys():
ifkeyin user2_data .keys():
distance +=pow(float(user1_data[key])-float(user2_data[key]),2)
return1/(1+sqrt(distance))
4.5 推荐模块的实现
根据相似度用户对电影的评分,对某个用户未观看过的电影进行兴趣推荐,并根据电影评分值降序进行TOP-N推荐。本系统中为某个用户推荐了评分排名前5的电影,其Python实现关键代码如下:
defrecom_user(user):
#给user用户推荐评分排名前5的电影
top_sim_user=top10_simliar(user)[0][0]
items=data_dict[top_sim_user]
recommendations=[]
foritemin items.keys():
ifitemnot in data_dict[user].keys():
recommendations .append((item,items[item]))
recommendations.sort(key=lambda val:val[1],reverse=True)
returnrecommendations[:5]
4.6 輸出推荐结果
调用主函数,为用户3推荐5部未观看过的电影,得到推荐结果如图2所示。
Recomm_user = recom_user('3')
for movie, rating in Recomm_user:
print('给3号用户推荐的电影:%-25s' % movie, '评分:%.6f' % float(rating))
4.7 用户相似度比较
图3是用户3通过两种算法得到的用户相似度比较结果。根据余弦相似度计算得到与用户3相似的前10个用户集合,从图中可以看出此集合用户与用户3的余弦相似度值均接近于1,表示该集合用户相似度非常高;同时,此集合用户与用户3的欧氏距离值均在0—0.5之间,表示这10个用户的欧氏相似度是正相关。
5 结语
本文依据推荐系统的相关技术,构建了推荐系统结构图,使用协同过滤算法和 Python语言实现了基于用户的协同过滤推荐系统,并通过实验验证了用户相似度的算法。该系统具有普适性,可以在多个领域主动为用户推荐其感兴趣的商品,满足其个性化需求。在未来的工作中,将优化算法,综合构建用户兴趣模型,进一步提高推荐系统性能和推荐精度。
参考文献:
[1] Isinkaye F O,Folajimi Y O,Ojokoh B A.Recommendationsystems:Principles,methods and evaluation[J].Egyptian Informatics Journal,2015,16(3):261-273.
[2] 项亮.推荐系统实践[M].北京:人民邮电出版社,2012.
[3] 李锋,冷娜.协同过滤的纺织面料推荐系统[J].计算机应用,2018,38(z2):115-118.
[4] 杨震,司书勇,李超阳.基于用户隐式兴趣模型的信息推荐技术研究[J].山东大学学报,2017(52):1-7.
[5] The MovieLens Datasets: History and Context. ACM Transactions on Interactive Intelligent Systems (TiiS) 5, 4: 19:1-19:19. https://doi.org/10.1145/2827872.
[6] 董付国.Python程序设计开发宝典[M].北京:清华大学出版社,2017.
【通联编辑:光文玲】