协同过滤与矩阵分解
这里主要介绍几个推荐系统的模型。
推荐系统模型是最重要的一块,因为推荐模型直接决定了最终物品排序的结果,它的好坏也直接影响着推荐效果的优劣。而且从某种意义上讲,推荐系统的整体架构都是围绕着推荐模型搭建的,用于支持推荐模型的上线、训练、评估、服务。
这里讲解的是 最经典的”协同过滤“。
协同过滤算法的基本原理
我们知道”用户行为数据是推荐系统最常用,也是最关键的数据。用户的潜在兴趣、用户对物品的评价好坏都反应在用户的行为历史中“。
而协同过滤算法,就是一种完全依赖用户和物品之间行为关系的推荐算法,它背后的原理就是”协同大家的反馈、评价和意见一起对海量的信息进行过滤,从中筛选出用户可能感兴趣的信息“
具体来看一个电影推荐例子:
首先,可以看到,电商网站的商品库里一共有4件商品:一个游戏机、一个小说、一本杂志,以及一台电视机。假设现在有一名用户X访问了这个电商网站,电商网站的推荐系统需要决定是否推荐电视机给用户X。
为了进行这项预测,推荐系统可以利用的数据有用户X对其他商品的历史评价数据,以及其他用户对这些商品的历史评价数据。上图(b)中用绿色”点赞“的标志表示好评,用红色”踩“的方式表示差评。这样一来,用户、商品和评价记录就构成了带有标识的有向图。
接下来为了方便计算,我们把有向图转成矩阵的形式,这个矩阵表示了物品共同出现的情况,因此被称为”共现矩阵“。其中,用户作为矩阵行坐标,物品作为列坐标,我们再把”点赞“和”踩“的用户行为数据转换成矩阵中相应的元素值。这里,我们将点赞值设为1, 踩的值设为-1, 没有数据 置为 0,(如果用户对物品有具体的评分,那共现矩阵中的元素值可以取具体的评分值,没有数据时默认评分也可以取评分的均值)
生成共现矩阵之后,推荐问题就转成了预测矩阵中问号元素的问题(图d)。由于协同过滤算法中,推荐的原理是让用户考虑与自己兴趣相似的用户的意见,因此我们预测的第一步就是找到与用户x兴趣最相似的n个用户(这里的top n用户是一个超参数),然后综合相似用户对”电视机“的评价,得出用户X对”电视机“评价的预测。
从共现矩阵中我们可以知道,用户B和C由于跟用户X的行向量近似,被选为Topn(n=2)相似用户,接着在图e中,我们可以看到,用户B和用户C对电视机的评价均为负面的,因为相似用户对电视机的评价都是负面的,所以我们可以预测出用户X对电视机的评价也是负面的,在实际推荐过程中,推荐系统不会向用户X推荐电视机这一物品。
到这里,协同过滤算法流程就结束了。这里有2个不严谨的地方:1. 用户相似度该怎么定义,2. 最后我们预测用户X对电视机的评价也是负面的,这个负面程度应该有一个分数来衡量,但是这个推荐分数如何计算呢?
计算用户相似度
因为有共现矩阵,每个用户对应的行向量其实就可以当作一个用户的Embedding向量。
- 余弦相似度: 最经典的方式就是利用余弦相似度,衡量用户向量i和j之间的夹角大小,夹角越小,余弦相似度越大,两个用户越相似。
- 其他方法:皮尔逊相关系数、欧式距离等。
用户评分的预测
在获得topn个相似用户后,利用Topn用户生成最终的用户u对物品p的评分是一个比较直接的过程。最常用的方式是,利用用户相似度和相似用户评价的加权平均值,来获得目标用户的评价预测:
R
u
,
p
=
∑
s
∈
S
(
w
u
,
s
∗
R
s
,
p
)
∑
s
∈
S
w
u
,
s
R_{u,p} = \frac {\sum_{s \in S}(w_{u,s}*R_{s,p})} {\sum_{s \in S}w_{u,s}}
Ru,p=∑s∈Swu,s∑s∈S(wu,s∗Rs,p)
其中,权重
w
u
,
s
w_{u,s}
wu,s是用户u和用户s的相似度,
R
s
,
p
R_{s,p}
Rs,p是用户s对物品p的评分。
在获得用户u对不同物品的评价预测后,最终的推荐列表根据评价预测得分进行排序即可得到,到这里,我们完成了协同过滤的全部推荐过程。
矩阵分解算法
虽然说协同过滤是公认的经典推荐算法,它的缺点也很明显,共现矩阵往往非常稀疏,在用户历史行为很少的情况下,寻找相似用户的过程并不准确。于是Netflix对协同过滤算法进行了改进,提出了矩阵分解算法,加强了模型处理稀疏矩阵的能力。
下面解释一下什么叫矩阵分解,Netflix的矩阵分解论文中截图的示意图,来比较协同过滤和矩阵分解的原理。
上图左侧是协同过滤: 协同过滤算法找到用户可能喜欢的视频的方式很直观,就是利用用户观看历史,找到跟目标用户joe看过同样视频的相似用户,然后找到这些相似用户喜欢看的其他视频,推荐给目标用户joe.
矩阵分解算法 则是期望为每一个用户和视频生成一个隐向量,将用户和视频定位到隐向量的表示空间上(图右侧),距离相近的用户和视频表明兴趣特点接近,在推荐过程中,我们就应该把距离相近的视频推荐给目标用户。比如,如果希望为用户Dave推荐视频,我们可以找到离Dave的用户向量最近的两个视频向量,分别是《Ocean‘s11》和《The lion king》,然后我们可以根据向量距离由近到远的顺序生成Dave的推荐列表。
矩阵分解的主要过程,就是先 分解 协同过滤生成的共现矩阵,生成用户和物品的隐向量,再通过用户和物品隐向量间的相似性进行推荐。
那这个过程的关键就是在于如何分解这个共现矩阵。从形式上来看,矩阵分解的过程是直观的,就是把一个mxn的共现矩阵,分解成一个mk的用户矩阵和lkn的物品矩阵相乘的形式。
有了用户矩阵和物品矩阵,用户隐向量和物品隐向量就非常好提取了,分别是对用户矩阵的行向量和物品矩阵的列向量。
那关键问题是: 通过什么方法把共现矩阵分解开呢?最常用的是梯度下降。梯度下降就是通过求取偏导的形式来更新权重。为了实现梯度下降,需要定一个损失函数L,定义好损失函数才能通过求导的方式找到梯度方向,这里给出矩阵分解损失函数的定义:
这个目标函数里面,
r
u
i
r_{ui}
rui是共现矩阵里面用户u对物品i的评分,qi是物品向量,pu是用户向量。通过目标函数的定义我们可以看到,我们要求的物品向量和用户向量,是希望让物品向量和用户向量之积跟原始的评分之差的平方尽量小。简单来说就是希望用户矩阵和物品矩阵的乘积尽量接近原来的共现矩阵(用户对物品的评分)。
在通过训练得到用户隐向量和物品隐向量之后,在服务器内部的推荐过程跟Embedding推荐是一样的。
总结
协同过滤是协同大家的反馈、评价和意见,对海量的信息进行过滤。从中筛选出用户感兴趣信息的一种推荐算法。 (1. 根据用户行为历史创建共现矩阵,2. 根据共现矩阵查找相似用户,3. 根据相似用户喜欢的物品,推荐目标用户喜欢的物品)
协同过滤处理稀疏矩阵的能力比较差,因此矩阵分解算法被提出,通过分解共现矩阵,生成用户向量矩阵和物品向量矩阵,进而得到用户隐向量和物品隐向量,最后可以把这些隐向量当作用户emebdding和物品embedding来处理。