协同过滤算法----电影推荐系统
一、前言从0构建AI推荐系统好久没继续深入研究了,一方面因为工作较忙,另一方面在准备task任务系列,从0开始一步步完成简单框架的搭建与应用。最近看到一篇文件介绍电影推荐系统,感觉非常有意思,抽半天的时间动手实践了一下,本文记录学习电影推荐系统的全过程。本文完整代码已经上传至GitHub:简单的电影推荐系统。二、相关环境介绍编程语言:python编辑器:pycharm第三方...
一、前言
从0构建AI推荐系统好久没继续深入研究了,一方面因为工作较忙,另一方面在准备task任务系列,从0开始一步步完成简单框架的搭建与应用。最近看到一篇文件介绍电影推荐系统,感觉非常有意思,抽半天的时间动手实践了一下,本文记录学习电影推荐系统的全过程。
本文完整代码已经上传至GitHub:简单的电影推荐系统。
二、相关环境介绍
编程语言:python
编辑器:pycharm
第三方库:pandas、numpy、sklearn
数据集:https://grouplens.org/datasets/movielens/ ml-100k.zip (size: 5 MB, checksum)
注:
1. Scikit-learn,简称sklearn,一个用于Python编程语言的免费软件机器学习库,支持分类、回归、降维和聚类四大机器学习算法,包含特征提取、数据处理和模型评估三大模块,支持k均值、支持向量机、随机森林、梯度增强等常见算法。
另外,由于sklearn建立在NumPy、Scipy和matplotlib库基础上,利用这几大模块的优势,可以大大提高机器学习的效率。sklearn拥有着完善的文档,上手容易,具有着丰富的API,在学术界颇受欢迎。同时sklearn内置了大量数据集,节省了获取和整理数据集的时间。
2. 本文使用的数据集较少且时间较早,但可以用来学习与练手,换作别的数据集后,实现的推荐方式大同小异。
三、构建电影推荐系统
3.1 推荐系统简介
简介:使用推荐算法进行数据挖掘,发现用户可能需要的商品。
推荐系统一般由以下三部分构成:
1. 基础数据部分(数据的质量决定推荐系统的上限,各种推荐算法无限逼近这个上限)
2. 推荐算法系统(一般由多个算法组成的推荐模型)
3. 前端展示(直观、高效的展示效果往往更能引人入胜、说明问题)
常见的推荐算法包括以下:
1. 基于流行度的推荐算法(按热门推荐)
2. 协同过滤算法
基于用户的协同过滤算法(推荐和你类似的人喜欢的商品)
基于商品的协同过滤算法(推荐喜欢这个商品的人也喜欢的商品)
3. 基于内容的过滤算法(词权、word2vec、聚类)
4. 基于模型的推荐算法(多种机器学习算法)
5. 基于矩阵分解的推荐算法(LFM隐语义模型)
6. 混合算法(结合多种推荐算法)
3.2 数据预处理
在数据集中,主要用到三种数据:
u.user:用户信息表(包括用户ID,年龄,性别,职业,邮编)
u.data:电影评分表(包括用户ID,电影ID,评分值,评分时间戳)
u.item:电影信息表(包括电影ID,电影名,上映时间,网址,电影类型)
采用pandas.read_csv()方法读取三种数据,并对应别设定每列的名称。
def init():
'''
初始化,读入文件
:return: 用户表,评分表,电影明细表
'''
user_file = "E:\\ZX_relatedResources\\recommendation_movie_ml-100k\\u.user"
data_file = "E:\\ZX_relatedResources\\recommendation_movie_ml-100k\\u.data"
item_file = "E:\\ZX_relatedResources\\recommendation_movie_ml-100k\\u.item"
u_cols = ['user_id', 'age', 'sex', 'occupation', 'zip_code']
users = pd.read_csv(user_file, sep="|", names=u_cols, encoding='latin-1')
r_cols = ['user_id', 'movie_id', 'rating', 'unix_timestamp']
ratings = pd.read_csv(data_file, sep='\t', names=r_cols,encoding='latin-1')
i_cols = ['movie_id', 'movie_title' ,'release date','video release date', 'IMDb URL', 'unknown',
'Action', 'Adventure', 'Animation', 'Children\'s', 'Comedy', 'Crime', 'Documentary',
'Drama', 'Fantasy', 'Film-Noir', 'Horror', 'Musical', 'Mystery', 'Romance', 'Sci-Fi',
'Thriller', 'War', 'Western']
items = pd.read_csv(item_file, sep='|', names=i_cols, encoding='latin-1')
return users, ratings, items
3.3 构造用户电影矩阵
这一步主要是构造一个矩阵,每一行代表一个用户,每一列代表一部电影,用户与电影对应的矩阵元素则是用户对该电影的评分。
def constructUserMovieMatrix(users, ratings):
'''
构造用户-电影矩阵
:param users: 用户表
:param ratings: 打分表
:return: 用户对电影评分的矩阵
'''
num_users = users.user_id.unique().shape[0] #用户数
num_items = ratings.movie_id.unique().shape[0] #电影总数
data_matrix = np.zeros((num_users, num_items))
for line in ratings.itertuples():
data_matrix[line[1]-1, line[2]-1] = line[3]
return data_matrix
执行结果:
注:
- unique()方法去重;
- Shape[0] 返回表示DataFrame维度的元组;
- line 的内容示例如下: Pandas(Index=0, user_id=196, movie_id=242, rating=3, unix_timestamp=881250949)
由于每行数据从1开始,存入下标为0的矩阵时要 -1。
3.4 构建电影之间相似度矩阵
采用计算余弦相似度的方式,计算电影之间的相似度矩阵。
def calculationSimilarity(data_matrix):
'''
转置计算电影之间相似度矩阵,不转置计算用户之间相似度矩阵
:param data_matrix: 评分矩阵
:return: 电影之间的相似度矩阵
'''
user_similarity = cosine_similarity(data_matrix, dense_output=True)
item_similarity = cosine_similarity(data_matrix.T, dense_output=True)
return item_similarity
注:转置是计算电影之间的相似度矩阵,不转置则计算用户之间的相似度矩阵!!
执行结果:
3.5 计算推荐电影
利用电影数据集中电影的相似程度,输入一部电影名或部分电影名(主要利用contains()方法),可以返回相似电影的电影名、相似度、平均评分、评分数。
def rec_sys(items,ratings, item_similarity, keywords, k):
'''
推荐系统
:param items: 电影明细表
:param ratings: 评分表
:param item_similarity: 电影相似度矩阵
:param keywords: 输入的电影名称或关键字
:param k: 推荐个数
:return: 推荐电影结果列表
'''
movie_list = [] # 存储推荐电影结果列表
movie_id = list(items[items['movie_title'].str.contains(keywords)].movie_id)[0] # 获得电影的id
movie_similarity = item_similarity[movie_id - 1] # 计算该电影的余弦相似度数组
movie_similarity_index = np.argsort(-movie_similarity)[1:k + 1] # 返回前k+1个最高相似度的索引位置
for index in movie_similarity_index:
rec_movie = list(items[items['movie_id'] == index + 1].movie_title) # 电影名
rec_movie.append(movie_similarity[index]) # 相似度
rec_movie.append(ratings[ratings['movie_id'] == index+1].rating.mean()) # 平均评分
rec_movie.append(len(ratings[ratings['movie_id'] == index+1])) # 评分用户数
movie_list.append(rec_movie)
return movie_list
执行结果:
四、总结
此电影推荐系统相对来说较为简单,过程比较清晰,处理的数据也不是很复杂,重点在于理解基于内容的协同过滤算法。
当然,数据集中涵盖电影的分类信息,可以尝试采用聚类算法将相似的电影聚类,换一个新的角度提高推荐算法的准确性。
五、参考链接
https://www.cnblogs.com/lianyingteng/p/7811126.html
更多推荐
所有评论(0)