推荐系统最常见的两种场景为评分预测与排序。评分预测的典型场景为豆瓣上一个用户对电影的评分,淘宝上对某个商品的评分。排序的场景更为普遍,比如信息流业务中,从海量的内容中挑选出最合适的topN内容给用户展示,就是一个典型的排序问题。
推荐系统中非常经典的技术之一就是矩阵分解(Matrix Factorization)。矩阵分解具有优秀的可扩展性,而且实现起来也不困难,因此在实际中使用非常广泛。下面我们针对推荐系统中的矩阵分解相关内容做一个详细梳理。
以最经典的电影评分为例,通常将用户与i电影表示为二维矩阵,其中矩阵的元素表示用户对电影的评分,分数越高,表示用户对电影越喜欢,而?表示评分记录缺失。在实际中,评分矩阵一般都是非常稀疏的,因为电影的数量有很多,用户看过的电影必然是少数,评分的更少,所以这个矩阵会极度稀疏。因此实际项目中,如何根据比较少的数据来预测或者填充未观测到的数据一直是一个比较重要的课题,而矩阵分解就是解决这个问题非常好的一种方式。
说到矩阵分解,一般先会提到特征值分解(Eigen decomposition),或者说谱分解(Spectral decomposition)。
首先我们明确一点,矩阵乘法,其实对应的是一个变换,是把任意的一个向量变成另外一个方向或者长度的新向量。如果矩阵对某些向量只发生伸缩变换,不产生旋转效果,那么这些向量就称为这个矩阵的特征向量,伸缩的比例就是特征值。
比如矩阵 A = [ 3 0 0 1 ] A = \left[ \begin{matrix} 3 & 0 \\ 0 & 1 \\ \end{matrix} \right] A=[3001]
[ 3 0 0 1 ] . [ x y ] = [ 3 x y ] \left[ \begin{matrix} 3 & 0 \\ 0 & 1 \\ \end{matrix} \right] . \left[ \begin{matrix} x \\ y \\ \end{matrix} \right] = \left[ \begin{matrix} 3 x \\ y \\ \end{matrix} \right] [3001].[xy]=[3xy]
因此,矩阵A乘以一个向量 (x,y)的结果是:沿X轴拉伸三倍,沿Y轴拉伸一倍。
(以上例子来自网络)
对于一个矩阵A(A为方阵),一定有
A v = λ v A v = \lambda v Av=λv
此时 λ \lambda λ为特征向量 v v v对应的特征值。而特征值分解为
A = Q Σ Q − 1 A = Q \Sigma Q^{-1} A=QΣQ−1
其中,Q是A的特征向量组成的矩阵。
输入公式比较麻烦,大家参考一下手写的特征值分解过程。是不是有上大学时候学线性代数的感觉。
上面特征值分解比较麻烦的一点,在于要求矩阵A为方阵。但是实际中,大部分矩阵不为方阵,这个时候奇异值分解就可以大显身手了。
关于奇异值分解的原理,具体可以参考SVD分解
经典的SVD分解,要求矩阵是稠密的,否则无法进行分解。同事,分解过程中有求逆运算,时间复杂度为 O ( n 3 ) O(n^3) O(n3),复杂度比较高。因此,人们想了各种办法来优化SVD分解。
Simon Funk提出的方案被称为FunkSVD。FunkSVD不将矩阵分解为三个矩阵U, Σ \Sigma Σ,V,而是分解为2个低秩的user-item矩阵,降低了系统的复杂度
优化的目标函数为
min q ∗ , p ∗ ∑ ( u , i ) ( r u i − q i T p u ) 2 \min \limits_{q^*,p^*} \sum \limits_{(u, i)} (r_{ui} - q_i^Tp_u) ^ 2 q∗,p∗min(u,i)∑(rui−qiTpu)2
核心思想事通过最小化观测数据的MSE,讲user与item的用一个低秩的隐向量表示出来。同时,还可以加上L2正则
min q ∗ , p ∗ ∑ ( u , i ) ( r u i − q i T p u ) 2 + λ ( ∣ ∣ q i ∣ ∣ 2 + ∣ ∣ p u ∣ ∣ 2 ) \min \limits_{q^*,p^*} \sum \limits_{(u, i)} (r_{ui} - q_i^Tp_u) ^ 2 + \lambda (||q_i||^2 + ||p_u||^2) q∗,p∗min(u,i)∑(rui−qiTpu)2+λ(∣∣qi∣∣2+∣∣pu∣∣2)
优化求解的方法可以通过传统的GD或者SGD方法来求解。
BiasSVD是在FunkSVD基础上的改进。其基本原理如下:不同user与不同item天生就有"bias"。比如有的用户给所有的item打分都很高,而有的item,因为位置等客官因素,打分也比一般的item要高。所以,我们在预测评分的时候,需要对这些"bias"有所体现。因此预测评分
r ^ u i = μ + b u + b i + q i T p u \hat{r}_{ui} = \mu + b_u + b_i + q_i^Tp_u r^ui=μ+bu+bi+qiTpu
其中, μ \mu μ表示整体的平均分数, b u b_u bu是user的偏置,而 b i b_i bi是item的偏置。
所以最终的目标函数变为
min q ∗ , p ∗ , b i , b u ∑ ( u , i ) ( r u i − q i T p u ) 2 + λ ( ∣ ∣ q i ∣ ∣ 2 + ∣ ∣ p u ∣ ∣ 2 + ∣ ∣ b i ∣ ∣ 2 + ∣ ∣ b u ∣ ∣ 2 ) \min \limits_{q^*,p^*, b_i, b_u} \sum \limits_{(u, i)} (r_{ui} - q_i^Tp_u) ^ 2 + \lambda (||q_i||^2 + ||p_u||^2 + ||b_i||^2 + ||b_u||^2) q∗,p∗,bi,bumin(u,i)∑(rui−qiTpu)2+λ(∣∣qi∣∣2+∣∣pu∣∣2+∣∣bi∣∣2+∣∣bu∣∣2)
SVD++是在SVD的基础上加入隐式反馈,使用user的各种历史浏览记录,历史评分记,item的各种历史浏览记录,历史评分记录等作为新的参数加入到模型中。
r ^ u i = μ + b u + b i + q i T ( p u + I u − 1 ∑ j ∈ I u y j ) \hat{r}_{ui} = \mu + b_u + b_i + q_i^T(p_u + I_u^{-1}\sum \limits_ {j \in I_u} y_j) r^ui=μ+bu+bi+qiT(pu+Iu−1j∈Iu∑yj)
其中, I u I_u Iu为user i所产生隐反馈行为的物品集合, y i y_i yi为隐藏的“评价了电影 j”反映出的个人喜好偏置。
NMF为非负矩阵分解。在其他矩阵分解方法的基础之上,新增加了一个约束:分解出来的矩阵均为非负的。
在大部分矩阵分解的方法中,原始矩阵被分解为两个低秩矩阵的形式,即使原始矩阵元素都非负,但是也不能保证分解出来的小矩阵也非负。这就导致了分解结果的可解释性,或者说跟现实世界的认知,差别比较大,因为现实世界很多场景事负数是没有意思的。比如用SVD做图像压缩,像素显然不能为负数。比如td-idf值,也不能为负数。
因此,非负矩阵分解是有现实意义的。ALS算法里面就用到了NMF。
假设有矩阵A
A = P T Q A = P^TQ A=PTQ
其中, P > = 0 , Q > = 0 P >= 0, Q >= 0 P>=0,Q>=0
首先我们来看one-class问题。预测用户行为的时候,大部分的时候只有用户正向选择的行为记录(即正样本)。如果我们使用0-1矩阵表示这类问题,1表示用户喜欢该物品,0的话却不一定事用户不喜欢,也有可能只是没有看到。
对于上面的情况,有三种解决方式。
第一是通过标注负样本来转化为一个传统的协同过滤问题,很明显这样代价很高,需要大量的人力来标注,而且标注的结果也不一定对。
第二是将所有缺失值作为负样本。这样做的缺点就是我们前面提到的,缺失的样本不一定为负样本,只是用户没看到而已。
第三是将缺失值看成未知,忽略所有缺失值。这种方法的结果就是预测结果也只有正类。
要解决上面问题就是如何填充这些缺失值,也就是如何收集负样本,有下面几种方法
1.均匀采样,即把所有的缺失数据看作负样本,以相同的概率进行抽样。
2.偏重用户采样,即活跃度用户的负样本要多一点,对活跃用户来说,他没有产生行为的物品将会以更高的概率选作负样本。
3.偏重物品采样,即热门物品的负样本要多一点,对热门物品来说,曝光机会多,如果用户对它没有行为,则高概率是负样本。
上面第二种与第三种方法相对来说更合理。
加权正则化矩阵分解(Weighted Regularized Matrix Factorization, WRMF)是《Collaborative Filtering for Implicit Feedback Datasets》提出的,用于解决隐式反馈推荐。
定义隐式反馈的损失函数为
min ∑ ( u , i ) c u i ( p u i − q i T p u ) 2 + λ ( ∣ ∣ q i ∣ ∣ 2 + ∣ ∣ p u ∣ ∣ 2 + ∣ ∣ b i ∣ ∣ 2 + ∣ ∣ b u ∣ ∣ 2 ) \min \sum \limits_{(u, i)} c_{ui}(p_{ui} - q_i^Tp_u) ^ 2 + \lambda (||q_i||^2 + ||p_u||^2 + ||b_i||^2 + ||b_u||^2) min(u,i)∑cui(pui−qiTpu)2+λ(∣∣qi∣∣2+∣∣pu∣∣2+∣∣bi∣∣2+∣∣bu∣∣2)
在隐式反馈中,模型事没有评分的,因此在式子中 r u i r_{ui} rui被 p u i p_{ui} pui取代了, p u i p_{ui} pui就表示偏好,仅仅表示用户和物品之间有没有交互,而不表示评分高低或者喜好程度。比如用户和物品之间有交互就让pui等于1,没有就等于0。函数中的 c u i c_{ui} cui项,是表示用户对某个物品偏好的置信程度,比如交互次数较多的权重就会增加。例如我们用 d u i d_{ui} dui表示交互次数,那么置信度一般表示为
c u i = 1 + α d u i c_{ui} = 1 + \alpha d_{ui} cui=1+αdui
这里的 α \alpha α就是上面的置信参数,也是模型的一个超参数,需要模型验证。