Low Rank Matrix Factorization低阶矩阵分解

在上一篇笔记之二里面说到我们有五部电影,以及四位用户,每个用户对电影的评分如下,?表示未评分。

Movies\User User 1 User 2 User 3 User 4
Movie 1 5 5 0 0
Movie 2 5 0
Movie 3 4 0
Movie 4 0 0 5 4
Movie 5 0 0 5

那么我们可以把第一个表格里的内容转化成一个矩阵R:

R=55?005?4000?05500?40 R = [ 5 5 0 0 5 ? ? 0 ? 4 0 ? 0 0 5 4 0 0 5 0 ]
<script type="math/tex; mode=display" id="MathJax-Element-29"> R=\begin{bmatrix} 5 & 5 & 0 & 0\\ 5 & ? & ? & 0\\ ? & 4 & 0 & ?\\ 0 & 0 & 5 & 4\\ 0 & 0 & 5 & 0 \end{bmatrix}</script>
把参数θ和特征变量x也都表示成向量的形式:
X=(x(1))T(x(2))T...(x(nm))T X = [ − − − ( x ( 1 ) ) T − − − − − − ( x ( 2 ) ) T − − − . . . − − − ( x ( n m ) ) T − − − ]
<script type="math/tex; mode=display" id="MathJax-Element-30">X=\begin{bmatrix} ---(x^{(1)})^{T}---\\ ---(x^{(2)})^{T}---\\ ...\\ ---(x^{(n_{m})})^{T}--- \end{bmatrix}</script>
Θ=(θ(1))T(θ(2))T...(θ(nu))T Θ = [ − − − ( θ ( 1 ) ) T − − − − − − ( θ ( 2 ) ) T − − − . . . − − − ( θ ( n u ) ) T − − − ]
<script type="math/tex; mode=display" id="MathJax-Element-31">\Theta=\begin{bmatrix} ---(\theta^{(1)})^{T}---\\ ---(\theta^{(2)})^{T}---\\ ...\\ ---(\theta^{(n_{u})})^{T}--- \end{bmatrix}</script>
那么我们有: R=ΘTX R = Θ T X <script type="math/tex" id="MathJax-Element-32">R =\Theta^{T}X</script>,这种方法被称为:低秩矩阵分解(Low Rank Matrix Factorization)。

相关应用:

  • 找电影i相似的电影j:可以计算 x(i)x(j) ‖ x ( i ) − x ( j ) ‖ <script type="math/tex" id="MathJax-Element-33">\left \| x^{(i)} - x^{(j)} \right \|</script>两个特征向量的距离,其中距离最小的就是最相似的电影。

LFM (Latent Factor Model) 隐因子模型

接下来引申到LFM (Latent Factor Model) 隐因子模型,其中隐因子可以理解为一个用户喜欢一个电影的隐形原因,比如电影里面有他喜欢的romantic和action元素,还有他喜欢的某个演员或者导演编剧。如果另外一个电影有类似的元素跟演员,那么他很有可能会也喜欢这部电影。LFM的核心思路就是求出用户的θ向量和电影的x向量。
在评分矩阵 Rm,n R m , n <script type="math/tex" id="MathJax-Element-34">R_{m,n}</script>中,LFM中认为评分矩阵可以表示为 Rm,n=Pm,FQF,n R m , n = P m , F ⋅ Q F , n <script type="math/tex" id="MathJax-Element-35">R_{m,n}=P_{m,F}\cdot{Q_{F,n}}</script>即两个矩阵的乘积,其中F为隐因子的个数。我们设 r̂ ui r ^ u i <script type="math/tex" id="MathJax-Element-36">\hat {r}_{ui}</script>为用户u对物品i的评分。

r̂ ui=f=1FPufQfi r ^ u i = ∑ f = 1 F P u f Q f i
<script type="math/tex; mode=display" id="MathJax-Element-37">\hat{r}_{ui}=\sum_{f=1}^{F}{P_{uf}Q_{fi}}</script>
我们的目标是减少 r̂ ui r ^ u i <script type="math/tex" id="MathJax-Element-38">\hat {r}_{ui}</script>与 rui r u i <script type="math/tex" id="MathJax-Element-39">{r}_{ui}</script>之间的差距,并且为了防止过拟合加入了正则项。
min:CostFunctionJ=rui0(ru,ir̂ ui)2+λ(P2uf+Q2fi) m i n : C o s t F u n c t i o n J = ∑ r u i ≠ 0 ( r u , i − r ^ u i ) 2 + λ ( ∑ P u f 2 + ∑ Q f i 2 )
<script type="math/tex; mode=display" id="MathJax-Element-40">min: Cost Function J=\sum_{\color{red}{r_{ui}\ne0}}{(r_{u,i}-\hat{r}_{ui})^2}+\lambda(\sum{P_{uf}^2}+\sum{Q_{fi}^2})</script>
通过梯度下降对代价函数求偏导,可以得出:
JP(t)uf=i,rui02(ru,ir̂ ui)Q(t)fi+2λP(t)uf ∂ J ∂ P u f ( t ) = ∑ i , r u i ≠ 0 − 2 ( r u , i − r ^ u i ) Q f i ( t ) + 2 λ P u f ( t )
<script type="math/tex; mode=display" id="MathJax-Element-41">\frac{\partial{J}}{\partial{P_{uf}^{(t)}}}=\sum_{\color{red}{i,r_{ui}\ne0}}{-2(r_{u,i}-\hat{r}_{ui})Q_{fi}^{(t)}}+2\lambda{P_{uf}^{(t)}}</script>
JQ(t)fi=u,rui02(ru,ir̂ ui)P(t)uf+2λQ(t)fi ∂ J ∂ Q f i ( t ) = ∑ u , r u i ≠ 0 − 2 ( r u , i − r ^ u i ) P u f ( t ) + 2 λ Q f i ( t )
<script type="math/tex; mode=display" id="MathJax-Element-42">\frac{\partial{J}}{\partial{Q_{fi}^{(t)}}}=\sum_{\color{red}{u,r_{ui}\ne0}}{-2(r_{u,i}-\hat{r}_{ui})P_{uf}^{(t)}}+2\lambda{Q_{fi}^{(t)}}</script>
在上一步可以使用随机梯度下降方法(SGD,Stochastic Gradient Descent),它比传统的梯度下降法需要更少的迭代次数就可以收敛,这里就不详细阐述了。

SVD (singular value decomposition) 奇异值分解

SVD的数学意义和理解可以参考这篇博客

这里的SVD推荐本质上是model-based,跟传统数学意义的SVD没有太大关系,只不过借鉴了SVD分解 R=USV R = U ∗ S ∗ V <script type="math/tex" id="MathJax-Element-43">R=U∗S∗V</script>这个形式,通过最优化方法进行模型拟合,求得 R=UV R = U ∗ V <script type="math/tex" id="MathJax-Element-44">R=U∗V</script>。

我们在刚刚上面提到的 r̂ ui r ^ u i <script type="math/tex" id="MathJax-Element-45">\hat{r}_{ui}</script>中加入偏置项:

r̂ ui=f=1FPufQfi+μ+bu+bi r ^ u i = ∑ f = 1 F P u f Q f i + μ + b u + b i
<script type="math/tex; mode=display" id="MathJax-Element-46">\hat{r}_{ui}=\sum_{f=1}^{F}{P_{uf}Q_{fi}}+\mu+b_u+b_i</script>
其中μ表示训练集中物品的所有评分的平均值。 bu b u <script type="math/tex" id="MathJax-Element-47">b_u</script>是用户偏置项,表示一个用户评分的平均值。 bi b i <script type="math/tex" id="MathJax-Element-48">b_i</script>是物品偏置项,表示一个物品被评分的平均值。偏置项是固有属性,每个用户和物品都有自己的值,代表该物品是否被大众喜爱程度或某个用户对物品苛刻程度。
带偏置的LFM又被称为SVD。加入偏置项之后我们可以得到新的代价函数:
J=rui0(ru,ir̂ ui)2+λ(P2uf+Q2fi+b2u+b2i) J = ∑ r u i ≠ 0 ( r u , i − r ^ u i ) 2 + λ ( ∑ P u f 2 + ∑ Q f i 2 + ∑ b u 2 + ∑ b i 2 )
<script type="math/tex; mode=display" id="MathJax-Element-49">J=\sum_{\color{red}{r_{ui}\ne0}}{(r_{u,i}-\hat{r}_{ui})^2}+\lambda(\sum{P_{uf}^2}+\sum{Q_{fi}^2}+\sum{b_u^2}+\sum{b_i^2})</script> 通过随机梯度下降可以求得:
b(t+1)u:=b(t)u+α(ru,ir̂ uiλb(t)u) b u ( t + 1 ) := b u ( t ) + α ∗ ( r u , i − r ^ u i − λ ∗ b u ( t ) )
<script type="math/tex; mode=display" id="MathJax-Element-50">b_u^{(t+1)}:=b_u^{(t)}+\alpha*(r_{u,i}-\hat{r}_{ui}-\lambda*b_u^{(t)})</script>
b(t+1)i:=b(t)i+α(ru,ir̂ uiλb(t)i) b i ( t + 1 ) := b i ( t ) + α ∗ ( r u , i − r ^ u i − λ ∗ b i ( t ) )
<script type="math/tex; mode=display" id="MathJax-Element-51">b_i^{(t+1)}:=b_i^{(t)}+\alpha*(r_{u,i}-\hat{r}_{ui}-\lambda*b_i^{(t)})</script>

SVD++ / TIME SVD ++

我们从上一步的BiasLFM(即SVD)继续演化就可以得到SVD++。
SVD++:User对Item i 有评分,则反映他对各个隐因子的喜好程度 yi=(yi1,yi2,...,yiF) y i = ( y i 1 , y i 2 , . . . , y i F ) <script type="math/tex" id="MathJax-Element-57">y_i=(y_{i1},y_{i2},...,y_{iF})</script>,是物品所携带的属性。

r̂ ui=f=1F(Puf+jN(u)Yjf|N(u)|)Qfi+μ+bu+bi r ^ u i = ∑ f = 1 F ( P u f + ∑ j ∈ N ( u ) Y j f | N ( u ) | ) Q f i + μ + b u + b i
<script type="math/tex; mode=display" id="MathJax-Element-58">\hat{r}_{ui}=\sum_{f=1}^{F}{(P_{uf}+\frac{\sum_{j\in{N(u)}}{Y_{jf}}}{\sqrt{|N(u)|}})Q_{fi}}+\mu+b_u+b_i</script>
其中 Nu N u <script type="math/tex" id="MathJax-Element-59">N_u</script>为User u 评价过的物品集合。
使用随机梯度下降可以求得Q与Y的偏导
rui^Qfi=Puf+jN(u)Yjf|N(u)| ∂ r u i ^ ∂ Q f i = P u f + ∑ j ∈ N ( u ) Y j f | N ( u ) |
<script type="math/tex; mode=display" id="MathJax-Element-60">\frac{\partial{\hat{r_{ui}}}}{\partial{Q_{fi}}}=P_{uf}+\frac{\sum_{j\in{N(u)}}{Y_{jf}}}{\sqrt{|N(u)|}}</script>
rui^Yjf=Qfi|N(u)| ∂ r u i ^ ∂ Y j f = Q f i | N ( u ) |
<script type="math/tex; mode=display" id="MathJax-Element-61">\frac{\partial{\hat{r_{ui}}}}{\partial{Y_{jf}}}=\frac{Q_{fi}}{\sqrt{|N(u)|}}</script>
其他偏导于SVD的一样,收缩因子取集合大小的根号是一个经验公式,并没有理论依据。
TIME SVD ++: 添加了时间动态,这里就不详细阐述了~

矩阵分解优劣势

主要的优势如下:

  • 比较容易编程实现,随机梯度下降方法依次迭代即可训练出模型。
  • 预测的精度比较高,预测准确率要高于基于领域的协同过滤以及基于内容CBR等方法。
  • 比较低的时间和空间复杂度,高维矩阵映射为两个低维矩阵节省了存储空间,训练过程比较费时,但是可以离线完成;评分预测一般在线计算,直接使用离线训练得到的参数,可以实时推荐。
  • 非常好的扩展性,如由SVD拓展而来的SVD++和 TIME SVD++。

矩阵分解的不足主要有:

  • 训练模型较为费时。
  • 推荐结果不具有很好的可解释性,无法用现实概念给分解出来的用户和物品矩阵的每个维度命名,只能理解为潜在语义空间。
Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐