电影推荐算法及python实现
导读:推荐算法在电⼦商务如淘宝,个⼈社交如微博等⽅⾯起着重要的作⽤。随着这些⽹站的飞速发展,这种个⼈推荐服务得到了更⼴泛的应⽤,例如抖⾳短视频推荐算法可以根据⽤户的观看习惯进⾏精准投放。本⼈通过查阅资料简单介绍了⽬前的协同推荐算法,并完成了电影推荐算法的python实现,附源码及实验数据。
⼀、协同过滤算法简介
协同过滤推荐算法是当下各推荐平台运⽤最为⼴泛的推荐算法,⾃开始被应⽤以来就对推荐系统的发展具有长⾜的影响。协同过滤的核⼼思想是根据与⽬标⽤户的兴趣偏好相似的最近邻的偏好来进⾏推荐。
协同过滤推荐算法可划分为两种,⼀种是基于内存的协同过滤,包括基于⽤户(user-based)的协同过滤推荐算法和基于物品(item-based)的协同过滤推荐算法,此类算法原理相对简单,适合初学者⼊门学习。另⼀种是基于模型(model-based)的协同过滤推荐算法,采⽤统计、机器学习等⽅法,通过⽬标⽤户的历史偏好搭建⽤户模型并据此进⾏推荐,此类⽅法需要采集⼤量的⽤户数据,对于初学者来说并不友好,本⽂不再详细介绍。
1.1基于⽤户(user-based)的协同过滤推荐算法
基于⽤户的协同过滤算法是通过⽤户的历史⾏为数据发现⽤户对视频内容的喜欢(如视频点赞,收藏,内容评论或分享),并对这些喜好进⾏度量和打分。根据不同⽤户对具有相同视频内容的态度和偏好程度计算⽤户之间的关系,在有相同喜好的⽤户间进⾏商品推荐。
图1 user-based协同过滤推荐算法⽰意图
在user-based协同过滤推荐算法中,user1和user3都收藏了product2和product3,通过对user的相似度计算,两者具有相近的距离。在后续的推荐过程中,user1独有的收藏视频product1和product4会被推荐给user3。
1.2基于物品(item-based)的协同过滤推荐算法
与user-based相似,Iterm-based也需要相似性计算,只不过user-based是针对于⽤户进⾏的,⽽Iterm-based是预先根据所有⽤户的历史偏好数据计算物品之间的相似性,然后把与⽤户喜欢的物品相类似的物品推荐给⽤户。
在图1中,Iterm-based⽅法以product为分析对象,对于product2,只要关注过product2的⽤户,同样会关注product3,两者将会被认为是同⼀类型。在对于user2进⾏推荐时,会根据其历史关注记录product2,推荐出同⼀类型的product3。
1.3优缺点对⽐
user-based的协同过滤推荐算法的最⼤优点是对推荐对象的结构没有特殊的要求,能够处理⾮结构化对象,如图⽚、⾳乐、电影等。再者,user-based的协同过滤具有可以推荐新内容的优点,能发掘在内容上截然不同的信息,⽤户对被推荐物品的内容信息也是事先⽆法预见的。这同时也是协同过滤推荐算法和Iterm-based推荐的⼀个很⼤的区别。
在⼀些场景中,⽤户数量远不如项⽬数量,项⽬维度远远⾼于⽤户维度。同时,⽤户兴趣爱好较为模糊,对于各类项⽬都会进⾏关注。因此,选择基于⽤户的⽅法能够⼤⼤降低空间复杂度。同时,如果项⽬的更新速度快,时效性要求⾼,如果采⽤Iterm-based的⽅法,新闻作为项⽬维度,不断更新项⽬相似度是不现实的。
在电⼦商务平台上,⽤户数量⼀般远远⾼于商品数量,⽤户维度远⾼于项⽬维度。同时商品没有很强的时效性,基于实际考虑,更适合采⽤基于项⽬的协同过滤推荐算法。
⼆、User-based协同过滤算法python实现
在电影推荐中,电影的数量远远⼤于⽤户的有效评价信息,采⽤Iterm-based的协同过滤算法带来了巨⼤的计算量以及较低的精度,为此我们选择了user-based的协同过滤算法进⾏电影推荐。
User-based协同过滤算法进⾏电影推荐分为三个阶段,第⼀个阶段利⽤⽤户的历史信息构建⽤户-电影评分矩阵。第⼆阶段通过选择合适的相似度公式对构建的评分矩阵计算⽤户之间的相似性。第三阶段,通过第三阶段得到⽤户间的相似性,利⽤近邻⽤户与当前⽤户间已评论电影的差异,利⽤预测公式进⾏预测。
2.1⽤户-电影评分矩阵的构建
我们从⽹络中获得到MovieLens数据集对⽤户-电影评分矩阵进⾏构建,数据集中包含610个⽤户对不同电影的10万个评分,分值为1⾄5,不同的⽤户通过电影ID相互联系,如下表所⽰:
表1 ⽤户-电影评分矩阵
12345……
电影ID
⽤户ID
抖音python入门教程144
22
33
45
54
……………………………………
python代码如下:
"""
multisim蜂鸣器在哪新建⼀个data字典存放每位⽤户评论的电影和评分, 如果字典中没有某位⽤户,则使⽤⽤户ID来创建这位⽤户,否则直接添加以该⽤户ID为key字典中
"""
file = open("./ml-latest-small/data.csv",'r', encoding='UTF-8')database的中文意思
data = {}
for line adlines():
line = line.strip().split(',')
if not line[0] in data.keys():
data[line[0]] = {line[3]:line[1]}
else:
data[line[0]][line[3]] = line[1]
2.2寻近邻⽤户
对于不同⽤户之间的相似性,常常通过简单的欧式距离进⾏计算[2],我们将采⽤person系数,也称为
⽪尔森积矩相关系数,对不同⽤户间的相似性进⾏计算。对于不同的⽤户,person系数取值在[-1,1]之间,如果person系数接近于1,则表⽰两个⽤户之间具有强相关性,两者对电影具有相同的个⼈喜好。当person系数接近于-1时,两个⽤户间完全负相关,及表⽰两⼈对电影的喜好完全对⽴。Person系数为0时,表⽰两个⽤户对电影的个⼈喜好并没有太多的联系。计算公式如下:
其中r表⽰person系数,i表⽰电影的编号,x和y分表表⽰两个不同的⽤户。对于每⼀位⽤户,我们通过person系数排序并筛选前10个⽤户作为近邻⽤户,根据他们对电影的评分进⾏电影的推荐。
2.3电影推荐
针对我们将要推荐的⽤户,我们通过近邻⽤户间的评分进⾏预测,预测公式如下:
如公式2所⽰,p为⽤户x对电影m的预测评分,s表⽰⽤户x的近邻⽤户,在本⽂中数量为10个。⽬标⽤户的近邻集合为Im。我们将最终得到的预测结果放到统⼀的集合中,并将预测结果进⾏降序排序,得到最终的电影推荐结果,并将结果输出。
程序运⾏结果如下:
本⽂只提供了欧式距离的算法,如果需要,可更改Euclidean,⽤numpy函数内的pccs = np.corrcoef(x, y)进⾏替换,完整代码如下:
import pandas as pd
from math import *
三角函数公式大全直角三角形import numpy as np
"""
读取movies⽂件,设置列名为’videoId', 'title', 'genres'
读取ratings⽂件,设置列名为'userId', 'videoId', 'rating', 'timestamp'
通过两数据框之间的 videoId 连接
保存'userId', 'rating', 'videoId', 'title'为data数据表
"""
movies = pd.read_csv("./ml-latest-small/movies.csv", names=['videoId', 'title', 'genres'])
ratings = pd.read_csv("./ml-latest-small/ratings.csv",names=['userId', 'videoId', 'rating', 'timestamp'])
data = pd.merge(movies, ratings, on='videoId')
data[['userId', 'rating', 'videoId', 'title']].sort_values('userId').to_csv('./ml-latest-small/data.csv',index=False)
"""
新建⼀个data字典存放每位⽤户评论的电影和评分, 如果字典中没有某位⽤户,则使⽤⽤户ID来创建这位⽤户,否则直接添加以该⽤户ID为key字典中
"""
file = open("./ml-latest-small/data.csv",'r', encoding='UTF-8')
data = {}
for line adlines():
line = line.strip().split(',')
if not line[0] in data.keys():
data[line[0]] = {line[3]:line[1]}
html登录注册页面代码验证码else:
data[line[0]][line[3]] = line[1]滑块滑轨润滑保养
"""
到两位⽤户共同评论过的电影,然后计算两者之间的欧式距离,最后算出两者之间的相似度,欧式距离越⼩两者越相似
"""
def Euclidean(user1, user2):
user1_data = data[user1]
user2_data = data[user2]
distance = 0
for key in user1_data.keys():
if key in user2_data.keys():
distance += pow(float(user1_data[key]) - float(user2_data[key]), 2)
distance += pow(float(user1_data[key]) - float(user2_data[key]), 2)
return 1 / (1 + sqrt(distance))
"""
计算某个⽤户与其他⽤户的相似度
"""
def top_simliar(userID):
res = []
for userid in data.keys():
# 排除与⾃⼰计算相似度
if not userid == userID :
simliar = Euclidean(userID, userid)
res.append((userid, simliar))
res.sort(key=lambda val: val[1])
return res[:4]
"""
从控制台输⼊需要推荐的⽤户ID,如果⽤户不在原始数据集中则报错,重新输⼊
"""
getIdFlag = 0
while not getIdFlag:
inputUid = str(input("请输⼊⽤户ID\n"))
try:
uid = data[inputUid]
getIdFlag = 1
except Exception:
print("⽤户ID错误,请重新输⼊\n")
"""
根据与当前⽤户相似度最⾼的⽤户评分记录,按降序排列,推荐出改⽤户还未观看的评分最⾼的10部电影"""
def recommend(user):
top_sim_user = top_simliar(user)[0][0]
items = data[top_sim_user]
recommendations = []
for item in items.keys():
if item not in data[user].keys():
recommendations.append((item, items[item]))
recommendations.sort(key=lambda val: val[1], reverse=True)  # 按照评分排序
return recommendations[:10]
"""
根据输⼊的⽤户ID,输出为他推荐的影⽚
"""
Recommendations = recommend(inputUid)
print("为⽤户" + inputUid + "推荐下列评分最⾼的⼗部影⽚\n")
for video in Recommendations:
print(video)
也可以添加免费获取

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。