49 | 推荐系统(上):如何实现基于相似度的协同过滤?
黄申
该思维导图由 AI 生成,仅供参考
你好,我是黄申。
个性化推荐这种技术在各大互联网站点已经普遍使用了,系统会根据用户的使用习惯,主动提出一些建议,帮助他们发现一些可能感兴趣的电影、书籍或者是商品等等。在这方面,最经典的案例应该是美国的亚马逊电子商务网站,它是全球最大的 B2C 电商网站之一。在公司创立之初,最为出名的就是其丰富的图书品类,以及相应的推荐技术。亚马逊的推荐销售占比可以达到整体销售的 30% 左右。可见,对于公司来说,推荐系统也是销售的绝好机会。因此,接下来的两节,我会使用一个经典的数据集,带你进行推荐系统核心模块的设计和实现。
MovieLens 数据集
在开始之前,我们先来认识一个知名的数据集,MovieLens。你可以在它的主页查看详细的信息。这个数据集最核心的内容是多位用户对不同电影的评分,此外,它也包括了一些电影和用户的属性信息,便于我们研究推荐结果是不是合理。因此,这个数据集经常用来做推荐系统、或者其他机器学习算法的测试集。
时至今日,这个数据集已经延伸出几个不同的版本,有不同的数据规模和更新日期。我这里使用的是一个最新的小规模数据集,包含了 600 位用户对于 9000 部电影的约 10 万条评分,最后更新于 2018 年 9 月。你可以在这里下载:http://files.grouplens.org/datasets/movielens/ml-latest-small.zip。
公开
同步至部落
取消
完成
0/2000
荧光笔
直线
曲线
笔记
复制
AI
- 深入了解
- 翻译
- 解释
- 总结
本文介绍了如何使用基于相似度的协同过滤推荐系统,并以MovieLens数据集为例进行详细讲解。作者首先介绍了数据集的基本信息和结构,然后提出了推荐系统的整体设计思路,包括用户评分的标准化、衡量用户或物品之间的相似度以及根据相似度给出预测得分。接着,作者给出了核心Python代码,包括加载数据、标准化评分数据、计算用户相似度矩阵和进行基于用户的协同过滤推荐等步骤。最后,通过一个具体的例子展示了推荐系统的效果,并解释了系统对用户喜好的预测合理性。整篇文章通俗易懂,结合实际代码示例,为读者提供了实现基于相似度的协同过滤推荐系统的详细指导。文章还提出了思考题,鼓励读者使用自己擅长的语言实现基于物品的协同过滤,并分享学习笔记。同时,作者也展望了下一节内容,将通过SVD奇异值分解来尝试自动划分电影类型并进行推荐。整体而言,本文内容丰富,涵盖了推荐系统的设计和实现,适合对推荐系统感兴趣的读者阅读学习。
仅可试看部分内容,如需阅读全部内容,请付费购买文章所属专栏
《程序员的数学基础课》,新⼈⾸单¥68
《程序员的数学基础课》,新⼈⾸单¥68
立即购买
© 版权归极客邦科技所有,未经许可不得传播售卖。 页面已增加防盗追踪,如有侵权极客邦将依法追究其法律责任。
登录 后留言
全部留言(6)
- 最新
- 精选
- qinggeouye# 优化了一下,运行时间减少一半以上 # https://github.com/qinggeouye/GeekTime/blob/master/MathematicProgrammer/49_recommendSystem/lesson49_2.py import numpy as np import pandas as pd from sklearn.preprocessing import scale import time """ 对 lesson49_1.py 优化:矩阵操作 """ # 运行开始时间 time_start = time.time() # 加载用户对电影对评分数据 df = pd.read_csv("ml-latest-small/ratings.csv") # 获取用户对数量和电影对数量 user_num = df["userId"].max() movie_num = df["movieId"].max() # 构造用户对电影的二元关系矩阵 user_rating = np.zeros((user_num, movie_num)) # 由于用户和电影的 ID 都是从 1 开始,为了和 Python 的索引一致,减去 1 df["userId"] = df["userId"] - 1 df["movieId"] = df["movieId"] - 1 for index in range(user_num): user_rating[index][df[df["userId"] == index]["movieId"]] = df[df["userId"] == index]["rating"] # 把二维数组转化为矩阵 x = np.mat(user_rating) # 对每一行对数据,进行标准化 x_s = scale(x, with_mean=True, with_std=True, axis=1) # 获取 XX' y = x_s.dot(x_s.transpose()) # 夹角余弦的分母 v = np.zeros((np.shape(y)[0], np.shape(y)[1])) v[:] = np.diag(y) # 获用户相似度矩阵 US , 对应位置上元素相除 us = y/v # 通过用户之间的相似度,计算 USP 矩阵 usp = np.mat(us).dot(x_s) # 求用于归一化的分母 按行求和 usr = np.sum(us, axis=1) # 进行元素对应的除法 归一化 p = np.divide(usp, np.mat(usr).transpose()) # 运行结束时间 time_end = time.time() print(p) print(np.shape(p)) print("程序运行耗时:", time_end - time_start)
作者回复: 感谢代码的优化🙏
2019-04-219 - 呵呵不太理解USP这个矩阵的具体意义是什么,黄老师能不能给解释一下
作者回复: US矩阵表示用户和用户之间的相似程度,对于给定某个用户a,我们认为他/她和其他用户b,c,d...n的相似度分别是0.1, 0.05, 0.3, 0.01...,这样用它左乘原始的评分矩阵X,就能得到基于这些权重,以及b,c,d...n这些人对物品评分的一个加权平均,而用这个加权平均作为给定用户a对该物品的综合评分。
2021-10-212 - 冄~老师好,感觉按照公式来看,USR作为分母,第一行应该是US的第一行元素求和(1+0.482+0.671+0=2.153),而不是USP的第一行求和(0.500+0.790+0.496=1.786)。否则会像文中一样,p矩阵每行求和为1也是因为USR这样计算导致的。代码部分usr[userId] = sum(us[userId])应该是对的。不知我理解得对不对?
作者回复: 我回头仔细看一下,可能是个笔误
2019-04-282 - 013923推荐系统1学习2022-09-23归属地:上海1
- 建强思考题: 基于物品的协同过滤的代码实现: # 前面的初始化步骤和评分标准化步骤和老师写的基于用户的协同过滤一致,不再重复 # 第一步:计算表示物品之间相似度的矩阵 IS # 由于内存不够,这里取所有用户对前100部电影的评价信息 x2_s = x_s[:,0:100] x2_s # 获取X'X y = (x2_s.transpose()).dot(x2_s) print("X'X的结果是':", y) # 获得物品相似度矩阵IS IS = [[0.0] * movie_num for i in range(movie_num)] for movieId1 in range(movie_num): for movieId2 in range(movie_num): # 通过矩阵Y中的元素,计算夹角余弦 IS[movieId1][movieId2] = y[movieId1][movieId2] / sqrt((y[movieId1][movieId1] * y[movieId2][movieId2])) # 第二步:基于物品的协同过滤推荐 # 通过物品之间的相似度,计算ISP矩阵 ISP = x2_s.dot(mat(IS)) # 求用于归一化的分母 ISR = [0.0] * movie_num for movieId in range(movie_num): ISR[movieId] = sum(IS[movieId]) # 进行元素对应的除法,完成归一化 p = divide(ISP, mat(ISR)) print(p)2021-01-03
- Paul Shan原始推荐数据可以找出用户之间的相似度,再求出所有用户对任意电影的评价,进而补上那些原始推荐数据中没有的配对。2019-10-18
收起评论