15 | 协同过滤:最经典的推荐模型,我们应该掌握什么?
协同过滤算法的基本原理
1
首先,我们可以看到,电商网站的商品库里一共有 4 件商品:一个游戏机、一本小说、一本杂志,以及一台电视机。假设,现在有一名用户 X 访问了这个电商网站,电商网站的推荐系统需要决定是否推荐电视机给用户 X。
2
为了进行这项预测,推荐系统可以利用的数据有用户 X 对其他商品的历史评价数据,以及其他用户对这些商品的历史评价数据。我在图 1(b) 中用绿色“点赞”的标志表示好评,用红色“踩”的标志表示了差评。这样一来,用户、商品和评价记录就构成了带有标识的有向图。
3
接下来,为了方便计算,我们将有向图转换成矩阵的形式。这个矩阵表示了物品共同出现的情况,因此被称为“共现矩阵”。其中,用户作为矩阵行坐标,物品作为列坐标,我们再把“点赞”和“踩”的用户行为数据转换为矩阵中相应的元素值。这里,我们将“点赞”的值设为 1,将“踩”的值设为 -1,“没有数据”置为 0(如果用户对物品有具体的评分,那么共现矩阵中的元素值可以取具体的评分值,没有数据时的默认评分也可以取评分的均值)。
4
你发现了吗,生成共现矩阵之后,推荐问题就转换成了预测矩阵中问号元素(图 1(d) 所示)的值的问题。由于在“协同”过滤算法中,推荐的原理是让用户考虑与自己兴趣相似用户的意见。因此,我们预测的第一步就是找到与用户 X 兴趣最相似的 n(Top n 用户,这里的 n 是一个超参数)个用户,然后综合相似用户对“电视机”的评价,得出用户 X 对“电视机”评价的预测。
5
从共现矩阵中我们可以知道,用户 B 和用户 C 由于跟用户 X 的行向量近似,被选为 Top n(这里假设 n 取 2)相似用户,接着在图 1(e) 中我们可以看到,用户 B 和用户 C 对“电视机”的评价均是负面的。因为相似用户对“电视机”的评价是负面的,所以我们可以预测出用户 X 对“电视机”的评价也是负面的。在实际的推荐过程中,推荐系统不会向用户 X 推荐“电视机”这一物品。
6
到这里,协同过滤的算法流程我们就说完了。也许你也已经发现了,这个过程中有两点不严谨的地方,一是用户相似度到底该怎么定义,二是最后我们预测用户 X 对“电视机”的评价也是负面的,这个负面程度应该有一个分数来衡量,但这个推荐分数该怎么计算呢?
计算用户相似度
首先,我们来解决计算用户相似度的问题。计算用户相似度其实并不是什么难事,因为在共现矩阵中,每个用户对应的行向量其实就可以当作一个用户的 Embedding 向量。相信你早已经熟悉 Embedding 相似度的计算方法,那我们这里依葫芦画瓢就可以知道基于共现矩阵的用户相似度计算方法啦。最经典的方法就是利用余弦相似度了,它衡量了用户向量 i 和用户向量 j 之间的向量夹角大小。夹角越小,余弦相似度越大,两个用户越相似,它的定义如下:sim(i,j)=cos(i,j)=∣∣i∣∣×∥j∣∣i⋅j
用户评分的预测
矩阵分解算法的原理
这个时候你肯定觉得,矩阵分解不就是相当于一种 Embedding 方法嘛。没错,矩阵分解的主要过程,就是先分解协同过滤生成的共现矩阵,生成用户和物品的隐向量,再通过用户和物品隐向量间的相似性进行推荐。那这个过程的关键就在于如何分解这个共现矩阵了。从形式上看,矩阵分解的过程是直观的,就是把一个 mxn 的共现矩阵,分解成一个 mxk 的用户矩阵和 kxn 的物品矩阵相乘的形式(如图 3)。
矩阵分解算法的 Spark 实现
// 建立矩阵分解模型
val als = new ALS()
.setMaxIter(5)
.setRegParam(0.01)
.setUserCol("userIdInt")
.setItemCol("movieIdInt")
.setRatingCol("ratingFloat")
//训练模型
val model = als.fit(training)
//得到物品向量和用户向量
model.itemFactors.show(10, truncate = false)
model.userFactors.show(10, truncate = false
其实,矩阵分解算法得出的结果,你完全可以把它当作 Embedding 来处理。具体怎么做呢?在讲 Redis 的时候,我们就已经实现过物品 Embedding 和用户 Embedding 的存储和线上预估的过程了,你可以直接参考它。最后,我建议你利用矩阵分解后的用户和物品隐向量,仿照其他 Embedding 的实现,在 Sparrow RecSys 中动手实现一下线上部署的过程,这样你就可以看到矩阵分解模型的实际效果了。
小结
这节课我们一起学习了协同过滤算法,以及它的后续算法矩阵分解,它是最经典的推荐算法。总结来说,协同过滤是一种协同大家的反馈、评价和意见,对海量的信息进行过滤,从中筛选出用户感兴趣信息的一种推荐算法。它的实现过程主要有三步,先根据用户行为历史创建共现矩阵,然后根据共现矩阵查找相似用户,再根据相似用户喜欢的物品,推荐目标用户喜欢的物品。但是协同过滤处理稀疏矩阵的能力比较差,因此,矩阵分解算法被提出了,它通过分解共现矩阵,生成用户向量矩阵和物品向量矩阵,进而得到用户隐向量和物品隐向量。你可以完全把最后的结果当作用户 Embedding 和物品 Embedding 来处理。针对这节课的重要知识点,我把它们都列在了下面的表格里,你可以看看。