化繁为简:推荐算法三视角

关于推荐系统,如果在忘掉所有的公式和代码,忘记所有的语言描述,脑海里就剩下几张图景,会是什么?一张二维表格,一个拓扑图,一条时间线 。这三幅图景,是我看待推荐算法的三种视角 。
视角一:矩阵视角
在脑中想象一个二维的表格,每一行代表一个用户,每一列代表一个物品,表格里的每一个点代表用户对物品的操作,这个操作可以是评分,点击,点赞 。其中,有些格子记录了行为,有些格子是空的 。到这里,我们就建立了基本的矩阵视角,推荐问题转化成了如何补上那些空格子 。

化繁为简:推荐算法三视角

文章插图
 
用户对物品的评分等于相似用户对该物品评分的加权平均值,这就是user-base的协同过滤了 。换一个方向,用户对物品的评分等于该用户对其他物品的评分按物品相似加权平均值,这就是item-base的协同过滤 。度量用户之间的相似度,把矩阵的一行——对物品的评分向量作为该用户的表示向量,那么用户之间可以计算向量的距离,可以选择任何距离公式,如余弦距离,皮尔森距离 。对于物品之间的相似度,换一个方向即可 。
对于任何两个物品,可以计算它们的评分差值 。具体来说,两个物品有一批共同的历史评分用户,也就是矩阵里两列有交集的行,每一行可以计算一个差值,将差值平均起来,作为两个物品的距离 。和上面的距离不同的,这个差值可以想象成物理中的位移,带着符号的 。推荐时,某用户对于某个物品的评分,等于某用户对其他物品评分加上这个位移,再进行平均得到的平均评分 。和上面的item-base一样的,都是列向量计算相似度,只不过相似度由距离变成了位移 。这就是著名的Slope-One算法 。
化繁为简:推荐算法三视角

文章插图
 
物品直接的相似度,除了上面的启发式算法,能不能通过数据本身学习所得?这就诞生了SLIM(Sparse Linear Methods)方法 。矩阵A是n*m评分矩阵,要学习一个n*m维的物品相似的矩阵W 。
A的每一行是用户的历史评分,w的每一列是每一个物品和该列对应物品的相似度,计算内积即为该用户对该列物品的评分,通过梯度下降训练来拟合真实评分 。其中,w非负体现了相似度的物理意义;对角线限制为0避免对角线全都学习到1完美过拟合;添加L1正则产生稀疏的w,使得结果在大规模物品集上可用;w的每一列的学习都可以看作一个线性回归模型,训练时可以彼此相互独立,因而可以分布式学习 。
化繁为简:推荐算法三视角

文章插图
 
在矩阵视角下,很自然可以进行矩阵分解 。SVD矩阵分解将n个用户m个物品的大矩阵分解成三个矩阵相乘,中间的矩阵越靠近左上角的特征值越大,代表矩阵分解的主要成分,也就是说保留左上角的
k*k维矩阵D,其余的都置为零,将原来的等于变为约等于 。将蓝色和红色的矩阵合并,得到一个
m*k维的矩阵,每一个行代表一个k维的用户向量,对于黄色矩阵保留其前k行(后面的不影响计算了),每一列代表一个物品向量,用户和物品向量的内积也就是矩阵相乘后对应矩阵的值,也就是空缺处的评分,将向量索引起来就可以推荐了 。
化繁为简:推荐算法三视角

文章插图
 
要使用SVD分解,待分解矩阵要是稠密的,稀疏的评分矩阵要按照统计学方法填充,如填充均值 。另外,SVD过拟合现象严重,泛化误差太大 。在2006年Netflix Prize的百万推荐大奖赛上,Simon Funk 在博客公开FunkSVD算法 。直接将评分矩阵分解成两个矩阵相乘,n*k维度的用户矩阵,每一行是用户的隐式向量表示,k*m维的物品矩阵,每一列是物品的隐式向量表示,用户和物品向量的内积即为预估的评分 。那如何进行分解呢?随机初始化矩阵,使用均方误差作为loss,梯度下降进行学习 。这个过程中还可以加入正则项,降低泛化误差 。由FunkSVD开始,基于Matrix factor(MF)的方法大放异彩 。
化繁为简:推荐算法三视角

文章插图
 

化繁为简:推荐算法三视角

文章插图
 
在MF的基础上,考虑推荐中的side information,如用户的年龄性别,物品的类目价格 。用户和物品自身或属性称作一个field,field之间可以两两进行矩阵分解,这个被称作二阶项,类似BiasSVD考虑每一个field都有一个bias,这个被称作一阶项,再加上一个全局的bias项 。这就是著名的Factorization machines(FM) 。


推荐阅读