协同过滤算法用于发现用户与物品之间的相关性,主要有两种:基于用户的和基于物品的。
基于用户:
用户1购买了物品A、B、C、D,并给了好评;而用户2也买了A、B、C,那么认为用户1和用户2是同类型用户,也可以把D推荐给用户2。
基于物品:
物品A和物品B都被用户1、2、3买过,则认为物品A和B有较高的相似度,而用户4买过物品A,则可以把物品B也推荐给用户4。
下面的案例是基于物品的协同过滤算法:
项目背景:某视频平台决定依据用户的观影记录做一个智能推荐系统,优化体验,提高用户粘性。
处理数据集
# 导入数据
import pandas as pd
movies = pd.read_excel('/kaggle/input/movie-name-and-category/Movie Name and Category.xlsx')
score = pd.read_excel('/kaggle/input/movie-name-and-category/Film rating.xlsx')
# 关联为一张表
df = pd.merge(movies, score, on='电影编号')
df.head()
代码详解:
merge()函数用来关联两个数据集,默认是内连接inner join。on:用于连接的列名,必须在两个DataFrame对象中都存在。
左连接的语法是:result2 = pd.merge(df1, df2, on='key', how='left');how:连接方式,包括‘left’,‘right’,‘outer’,‘inner’四种(默认为‘inner’)。
(数据集见评论区,数据集中有9712部电影和100836条评分)
运行结果:
转为数据透视表
# 将原始数据转换为数据透视表
user_movie = df.pivot_table(index='用户编号', columns='名称', values= '评分')
user_movie.tail()
代码详解:
pivot_table()是pandas的数据透视表函数,index表示索引,colums表示列名。
tail()表示展示尾部的几行,默认是5行。
运行结果:
计算皮尔逊相关系数
# 从数据透视表中提取各用户对《阿甘正传》的评分
FG = user_movie['阿甘正传(1994)']
# corrwith()函数计算《阿甘正传》与其他电影间的皮尔逊相关系数
corr_FG = user_movie.corrwith(FG) # 计算皮尔逊相关系数
similarity = pd.DataFrame(corr_FG, columns=['相关系数']) # 整合成二维表格
# 使用DataFrame的dropna()函数进行剔除空值
similarity.dropna(inplace=True)
# 展示5部电影的相关系数
similarity.head()
代码详解:
user_movie是我们上一步生成的透视表,先把目标要分析的电影筛选出来,并存到FG。
用corrwith()函数计算物品A与其他物品的皮尔逊相关系数。
由于存在空值,所以用dropna()函数剔除空值;空值的出现是因为:没有一个用户同时对这两部电影进行打分,那么就无法计算皮尔逊相关系数中的协方差,导致结果中出现了NaN值。
运行结果:
筛选结果
# 简单设置评分次数阈值为30,然后用sort_values()函数将表格按相关系数降序排列
similarity_new[similarity_new['评分次数'] > 30].sort_values(by='相关系数', ascending=False).head()
代码详解:
筛选评分次数在30以上的,是避免在样本量太少的情况下出现的偶然值。
sort_values()是排序函数,参数by是依据什么字段进行排序;ascending=False表示降序。
运行结果:
结果解读:《抓狂双宝》《致命吸引力》与《阿甘正传》的相似度较高,喜欢《阿甘正传》的用户可能也喜欢这两部电影,可以进行推荐。