基于矩阵分解的推荐算法

news2024/11/27 2:21:44

1.背景

  推荐系统的两大应用场景分别是评分预测(Rating Prediction)和Top-N推荐(Item Ranking)。其中评分预测主要用于评价网站,比如用户给自己看过的电影评多少分,或者用户给自己看过的书籍评价多少分,矩阵分解技术主要应用于评分预测问题;Top-N推荐常用于购物网站或获取不到显式评分的网站,通过用户的隐式反馈为用户提供一个可能感兴趣的Item列表,此排序任务需要排序模型进行建模。本文主要介绍如何利用矩阵分解来解决评分预测问题。

2.矩阵分解概述

  协同过滤技术可划分为基于内存/邻域的协同过滤(Memory-based CF)与基于模型的协同过滤技术(Model-based CF)。这里基于模型的协同过滤技术中矩阵分解(Matrix Factorization,MF)技术最为普遍和流行,因为它的可扩展性好并且易于实现。

  矩阵分解是一种隐语义模型。隐语义模型是通过隐含特征(Latent Factor)联系用户兴趣和物品,基于用户行为的自动聚类。在评分预测问题中,收集到的用户行为评分数据可用一个评分矩阵表示,矩阵分解要做的是预测出评分矩阵中缺失的评分,使得预测评分能反映用户的喜欢程度,从而可以把预测评分最高的前K个电影推荐给用户。为了预测缺失的评分,矩阵分解学习 U s e r User User 矩阵和 I t e m Item Item 矩阵,使得 U s e r User User矩阵 ∗ * I t e m Item Item矩阵​与评分矩阵中已知的评分差异最小,此时评分预测问题转化为了一个最优化问题,求解该最优化问题即可将评分矩阵分解成User矩阵和Item矩阵,从而可以计算出缺失的评分。

在评分预测问题中:

  • 构建 user -item 评分矩阵(数据是稀疏的,矩阵分解就是填充缺失的评分)
  • 学习 U s e r User User 矩阵和 I t e m Item Item 矩阵,使得评分与矩阵中已知的评分差异最小(最优化问题)

在这里插入图片描述

以电影评分预测为例,用评分矩阵表示收集到的用户行为数据,12个用户,9部电影。
在这里插入图片描述

  对上述用户-物品评分矩阵(12×9)进行矩阵分解,得到User(12×3)矩阵和Item(3×9)矩阵。观察下图User矩阵,可知用户的观影爱好体现在User向量上,观察Item矩阵,可知电影的风格体现在Item向量上,MF用user向量和item向量的内积去拟合评分矩阵中该user对该item的评分,内积的大小反映了user对item的喜欢程度,内积越大表明用户对该电影的喜爱程度高,反之用户对该电影的喜爱程度低。这里“动作”、“动画”、“爱情”为隐含特征,隐含特征个数k越大,隐类别分得越细,计算量越大。

在这里插入图片描述

把User矩阵与Item矩阵相乘,就能预测每个用户对每部电影的预测评分了,评分值越大,表示用户喜欢该电影的可能性越大,该电影就越值得推荐给用户。

在这里插入图片描述

3.矩阵分解目标函数

在用户-物品评分矩阵 R \bold R R 中, r u i r_{ui} rui 表示 用户 u u u 对 Item $i$ 的评分 , 当 r u i   > 0 r_{ui}\ \gt 0 rui >0 时,表示有评分,当   r u i   = 0 \ r_{ui}\ = 0  rui =0,表示没有评分。

在User矩阵 X \bold X X 中( M × k M×k M×k,用户数为M), x u x_u xu 表示用户 u u u 的向量,k维列向量。 X = [ x 1 , x 2 , . . . , x M ] \bold X=[x_1,x_2,...,x_M] X=[x1,x2,...,xM]

在Item矩阵 Y \bold Y Y 中( k × N k×N k×N,物品数为N), y i y_i yi 表示用户 i t e m i item_i itemi 的向量,k维列向量。 Y = [ y 1 , y 2 , . . . , y N ] \bold Y=[y_1,y_2,...,y_{N}] Y=[y1,y2,...,yN]

用户向量与物品向量的内积,表示用户 u u u 对物品 i i i 的预测评分。矩阵分解的目标函数为:
min ⁡ X , Y ∑ r u i ≠   0 ( r u i − x u T y i ) 2 + λ ( ∑ u ∣ ∣ x u ∣ ∣ 2 2 + ∑ i ∣ ∣ y i ∣ ∣ 2 2 ) \min \limits_{X,Y} \sum\limits_{r_{ui}\neq\ 0}\left(r_{ui}-x^T_uy_i\right)^2+\lambda\left(\sum\limits_{u}||x_u||^2_2+\sum\limits_{i}||y_i||^2_2\right) X,Yminrui= 0(ruixuTyi)2+λ(u∣∣xu22+i∣∣yi22)
上式前半部分表示的是User矩阵*Item矩阵与评分矩阵中已知的评分差异,后半部分是L2正则项,保证数值计算稳定性,防止过拟合。

4.目标函数最优化问题求解

  目标函数最优化问题的工程解法一般采用交替最小二乘法( Alternating Least Squares , ALS)或随机梯度下降(SGD)。 在实际应用中,交替最小二乘更常用一些,这也是社交巨头 Facebook 在他们的推荐系统中选择的主要矩阵分解方法。

4.1 交替最小二乘法(ALS)

交替最小二乘的核心是 “交替”,接下来看看 ALS 是如何 “交替” :

矩阵分解的最终任务是找到两个矩阵 X \bold X X Y \bold Y Y,让它们相乘后约等于原矩阵 R \bold R R
R m × n = X m × k   ×   Y n × k T \bold R_{m×n}=\bold X_{m×k}\ ×\ \bold Y_{n×k}^T Rm×n=Xm×k × Yn×kT
难就难在, X \bold X X Y \bold Y Y 两个都是未知的,如果知道其中一个的话,就可以按照线性代数标准解法求得,比如如果知道了 Y \bold Y Y,那么 X \bold X X 就可以这样算:
R m × n = X m × k   ×   Y n × k − 1 \bold R_{m×n}=\bold X_{m×k}\ ×\ \bold Y_{n×k}^{-1} Rm×n=Xm×k × Yn×k1
也就是 R \bold R R 矩阵乘以 Y \bold Y Y 矩阵的逆矩阵就得到了结果,反之知道了 X \bold X X 再求 Y \bold Y Y 也是一样。

交替最小二乘通过迭代的方式解决了这个鸡生蛋蛋生鸡的难题:

  1. 初始化随机矩阵 Y \bold Y Y 里面的元素值;
  2. Y \bold Y Y 矩阵当做已知的,直接用线性代数的方法求得矩阵 X \bold X X
  3. 得到了矩阵 X \bold X X后,把 X \bold X X 当做已知的,故技重施,回去求解矩阵 Y \bold Y Y
  4. 上面两个过程交替进行,一直到误差满足设定条件为止。

交替最小二乘法步骤:

  • S t e p 1 \bold Step1 Step1,固定 Y \bold Y Y 优化 X \bold X X
    min ⁡ X ∑ r u i ≠   0 ( r u i − x u T y i ) 2 + λ ∑ u ∣ ∣ x u ∣ ∣ 2 2 \min \limits_{X} \sum\limits_{r_{ui}\neq\ 0}\left(r_{ui}-x^T_uy_i\right)^2+\lambda\sum\limits_{u}||x_u||^2_2 Xminrui= 0(ruixuTyi)2+λu∣∣xu22
    将目标函数转化为矩阵表达形式:
    J ( x u ) = ( R u − Y u T x u ) T ( R u − Y u T x u ) + λ x u T x u J(x_u)=(R_u-Y^T_ux_u)^T(R_u-Y^T_ux_u)+\lambda x^T_ux_u J(xu)=(RuYuTxu)T(RuYuTxu)+λxuTxu
    其中 R u = [ r u i 1 , r u i 2 , . . . r u i n ] T R_u=[r_{ui_1},r_{ui_2},...r_{ui_n}]^T Ru=[rui1,rui2,...ruin]T 表示用户 u u u n n n 个物品的评分; Y u = [ y i 1 , y i 2 , . . . y i m ] Y_u=[y_{i_1},y_{i_2},...y_{i_m}] Yu=[yi1,yi2,...yim] n n n 个物品的向量。

    求解目标函数 J J J 关于 x u x_u xu 的梯度,并令梯度等于0,得到:
    ∂ J ( x u ) ∂ x u = − 2 Y u ( R u − Y u T x u ) + 2 λ x u = 0 \frac{\partial J(x_u)}{\partial x_u}=-2Y_u(R_u-Y^T_ux_u)+2\lambda x_u=0 xuJ(xu)=2Yu(RuYuTxu)+2λxu=0
    求解后可得:
    x u = ( Y u Y u T + λ I ) − 1 Y u R u x_u = (Y_uY^T_u+\lambda I)^{-1}Y_uR_u xu=(YuYuT+λI)1YuRu

  • S t e p 2 \bold Step2 Step2,固定 X \bold X X 优化 Y \bold Y Y
    min ⁡ Y ∑ r u i ≠   0 ( r u i − x u T y i ) 2 + λ ∑ i ∣ ∣ y i ∣ ∣ 2 2 \min \limits_{Y} \sum\limits_{r_{ui}\neq\ 0}\left(r_{ui}-x^T_uy_i\right)^2+\lambda\sum\limits_{i}||y_i||^2_2 Yminrui= 0(ruixuTyi)2+λi∣∣yi22

    • 将目标函数转化为矩阵表达形式:
      J ( y i ) = ( R i − X i T y i ) T ( R i − X i T y i ) + λ y i T y i J(y_i)=(R_i-X^T_iy_i)^T(R_i-X^T_iy_i)+\lambda y^T_iy_i J(yi)=(RiXiTyi)T(RiXiTyi)+λyiTyi
      其中 R u = [ r u 1 i , r u 2 i , . . . r u m i ] T R_u=[r_{u_1{i}},r_{u_2i},...r_{u_mi}]^T Ru=[ru1i,ru2i,...rumi]T表示 m m m个用户对个物品 i i i 的评分; X i = [ x u 1 , x u 2 , . . . x u m ] X_i=[x_{u_1},x_{u_2},...x_{u_m}] Xi=[xu1,xu2,...xum] m m m个用户的向量。

      求解目标函数 J J J关于 y i y_i yi 的梯度,并令梯度等于0,得到:
      ∂ J ( y i ) ∂ x i = − 2 X i ( R i − X i T y i ) + 2 λ y i = 0 \frac{\partial J(y_i)}{\partial x_i}=-2X_i(R_i-X^T_iy_i)+2\lambda y_i=0 xiJ(yi)=2Xi(RiXiTyi)+2λyi=0
      求解后可得:
      y i = ( X i X i T + λ I ) − 1 X i R i y_i = (X_iX^T_i+\lambda I)^{-1}X_iR_i yi=(XiXiT+λI)1XiRi

  • 重复 S t e p 1 \bold Step1 Step1 2 \bold 2 2,直到 X \bold X X Y \bold Y Y 收敛,每次固定一个矩阵,优化另一个矩阵,都是最小二乘问题

  除了针对显式评分矩阵,ALS还可以对隐式矩阵进行分解,将评分看成行为的强度,比如浏览次数,阅读时间等。 当 r u i   > 0 r_{ui}\ \gt 0 rui >0时, 表示用户 u u u对商品 i i i 有行为,当 r u i   = 0 r_{ui}\ = 0 rui =0, 表示用户 u u u对商品 i i i 没有行为。
P u i = { 1 r u i > 0 0 r u i = 0 P_{ui}=\begin{cases} 1 & r_{ui} \gt 0 \\ 0 & r_{ui} = 0 \end{cases} Pui={10rui>0rui=0
上式 P u i P_{ui} Pui 称为用户偏好:当用户 u u u对物品 i i i有过行为,认为用户 u u u对物品 i i i感兴趣, P u i P_{ui} Pui=1;当用户 u u u对物品 i i i没有过行为,认为用户 u u u对物品 i i i不感兴趣, P u i P_{ui} Pui=0.

对隐式矩阵进行分解的步骤:

  • 引入置信度( α \alpha α 为置信系数)
    c u i = 1 + α r u i c_{ui}=1+\alpha r_{ui} cui=1+αrui
      r u i   > 0 \ r_{ui}\ \gt 0  rui >0时, c u i c_{ui} cui r u i r_{ui} rui 线性递增,当 r u i   = 0 r_{ui}\ = 0 rui =0时, c u i   = 1 c_{ui}\ = 1 cui =1,即 c u i c_{ui} cui 最小值为1.

  • 目标函数
    min ⁡ X , Y ∑ u = 1 m ∑ i = 1 n c u i ( r u i − x u T y i ) 2 + λ ( ∑ u ∣ ∣ x u ∣ ∣ 2 2 + ∑ i ∣ ∣ y i ∣ ∣ 2 2 ) \min \limits_{X,Y} \sum\limits_{u=1}\limits^{m} \sum\limits_{i=1}\limits^{n}c_{ui}\left(r_{ui}-x^T_uy_i\right)^2+\lambda\left(\sum\limits_{u}||x_u||^2_2+\sum\limits_{i}||y_i||^2_2\right) X,Yminu=1mi=1ncui(ruixuTyi)2+λ(u∣∣xu22+i∣∣yi22)

  • ALS求解矩阵 X \bold X X Y \bold Y Y

ALS工具

  • spark ml库(官方推荐)
  • python代码:https://github.com/tushushu/imylu/blob/master/imylu/recommend/als.py

4.2 随机梯度下降SGD

  SGD基本思路是以随机方式遍历训练集中的数据,并给出每个已知评分的预测评分。用户和物品特征向量的调整就沿着评分误差越来越小的方向迭代进行,直到误差达到要求。所以,SGD不需要遍历所有的样本即可完成特征向量的求解。

矩阵分解的目标函数为:
J ( x u , y i ) = min ⁡ X , Y ∑ r u i ≠   0 ( r u i − x u T y i ) 2 + λ ( ∑ u ∣ ∣ x u ∣ ∣ 2 2 + ∑ i ∣ ∣ y i ∣ ∣ 2 2 ) J(x_u,y_i)= \min \limits_{X,Y} \sum\limits_{r_{ui}\neq\ 0}\left(r_{ui}-x^T_uy_i\right)^2+\lambda\left(\sum\limits_{u}||x_u||^2_2+\sum\limits_{i}||y_i||^2_2\right) J(xu,yi)=X,Yminrui= 0(ruixuTyi)2+λ(u∣∣xu22+i∣∣yi22)
分别求解 J ( x u , y i ) J(x_u,y_i) J(xu,yi)关于 x u x_u xu y i y_i yi的梯度如下:
∂ J ( x u , y i ) ∂ x u = ∑ u , r u i ≠ 0 − 2 ( r u i − x u T y i ) y i + ∑ u 2 λ ∣ ∣ x u ∣ ∣ 2 ∂ J ( x u , y i ) ∂ y i = ∑ i , r u i ≠ 0 − 2 ( r u i − x u T y i ) x u + ∑ i 2 λ ∣ ∣ y i ∣ ∣ 2 \begin{align} & \frac{\partial J(x_u,y_i)}{\partial x_u}=\sum\limits_{u,r_{ui}\neq 0}-2\left(r_{ui}-x^T_uy_i\right)y_i+\sum\limits_u 2\lambda||x_u||_2 \\[2ex] & \frac{\partial J(x_u,y_i)}{\partial y_i}=\sum\limits_{i,r_{ui}\neq 0}-2\left(r_{ui}-x^T_uy_i\right)x_u+\sum\limits_i 2\lambda||y_i||_2 \end{align} xuJ(xu,yi)=u,rui=02(ruixuTyi)yi+u2λ∣∣xu2yiJ(xu,yi)=i,rui=02(ruixuTyi)xu+i2λ∣∣yi2
不断更新矩阵 X \bold X X Y \bold Y Y
x u = x u + α ( ∑ u , r u i ≠ 0 − 2 ( r u i − x u T y i ) y i + ∑ u 2 λ 1 ∣ ∣ x u ∣ ∣ 2 ) y i = y i + α ( ∑ i , r u i ≠ 0 − 2 ( r u i − x u T y i ) x u + ∑ i 2 λ 2 ∣ ∣ y i ∣ ∣ 2 ) \begin{align} &x_u=x_u+\alpha(\sum\limits_{u,r_{ui}\neq 0}-2\left(r_{ui}-x^T_uy_i\right)y_i+\sum\limits_u 2\lambda_1||x_u||_2) \\[2ex] &y_i=y_i+\alpha(\sum\limits_{i,r_{ui}\neq 0}-2\left(r_{ui}-x^T_uy_i\right)x_u+\sum\limits_i 2\lambda_2||y_i||_2) \end{align} xu=xu+α(u,rui=02(ruixuTyi)yi+u2λ1∣∣xu2)yi=yi+α(i,rui=02(ruixuTyi)xu+i2λ2∣∣yi2)
由于 X \bold X X Y \bold Y Y 是两个不同的矩阵,通常分别采取不同的正则参数,如 λ 1 \lambda_1 λ1 λ 2 \lambda_2 λ2

5.矩阵分解算法

  MF(Matrix Factorization,矩阵分解)模型核心思想是通过两个低维小矩阵(一个代表用户embedding矩阵,一个代表物品embedding矩阵)的乘积计算,来模拟真实用户点击或评分产生的大的协同信息稀疏矩阵,本质上是编码了用户和物品协同信息的降维模型。

在这里插入图片描述

当训练完成,每个用户和物品得到对应的低维embedding表达后,如果要预测某个 U s e r i User_i Useri I t e m j Item_j Itemj 的评分的时候,只要它们做个内积计算 < U s e r i , I t e m j > <User_i,Item_j> <Useri,Itemj> ,这个得分就是预测得分。

5.1 Traditional SVD

5.1.1 回顾特征值和特征向量

特征值和特征向量的定义如下:
A x = λ x Ax=\lambda x Ax=λx
其中 A A A 是一个 n × n n×n n×n 的实对称矩阵, x x x 是一个 n n n 维向量,则我们说 λ \lambda λ 是矩阵 A A A 的一个特征值,而 x x x 是矩阵 A A A 的特征值 λ \lambda λ 所对应的特征向量。

求出特征值和特征向量有什么好处呢?

可以将矩阵A特征分解。

如果我们求出了矩阵 A A A n n n个特征值 λ 1 ≤ λ 2 ≤ . . . ≤ λ n λ_1≤λ_2≤...≤λ_n λ1λ2...λn,以及这 n n n个特征值所对应的特征向量 w 1 , w 2 , . . . w n {w_1,w_2,...w_n} w1,w2,...wn,如果这 n n n 个特征向量线性无关,那么矩阵 A A A 就可以用下式的特征分解表示:
A = W Σ W − 1 A=W\Sigma W^{-1} A=WΣW1
其中 W W W 是这 n n n 个特征向量所张成的 n × n n×n n×n 维矩阵,而 Σ \Sigma Σ 为这 n n n 个特征值为主对角线的 n × n n×n n×n 维矩阵。

一般我们会把 W W W的这 n n n个特征向量标准化,即满足 ∣ ∣ w i ∣ ∣ 2 = 1 ||w_i||_2=1 ∣∣wi2=1, 或者说 w i T w i = 1 w^T_iw_i=1 wiTwi=1,此时 W W W n n n 个特征向量为标准正交基,满足 W T W = I W^TW=I WTW=I,即 W T = W − 1 W^T=W^{−1} WT=W1, 也就是说 W W W为酉矩阵。
A = W Σ W T A=W\Sigma W^{T} A=WΣWT
注意到要进行特征分解,矩阵 A A A必须为方阵。那么如果 A A A不是方阵,即行和列不相同时,我们还可以对矩阵进行分解吗?答案是可以,此时我们的SVD登场了。

5.1.2 SVD

假设矩阵 A A A是一个 m × n m×n m×n的矩阵,那么我们定义矩阵 A A A的SVD为: :
A = U Σ V T A=U\Sigma V^{T} A=UΣVT
其中 U U U 是一个 m × m m×m m×m 的矩阵, Σ \Sigma Σ 是一个 m × n m×n m×n 的矩阵,除了主对角线上的元素以外全为 0 0 0 ,主对角线上的每个元素都称为奇异值, V V V是一个 n × n n×n n×n 的矩阵。 U U U V V V 都是酉矩阵,即满足 U T U = I , V T V = I U^TU=I,V^TV=I UTU=I,VTV=I。下图可以很形象的看出上面SVD的定义:

在这里插入图片描述

如何求出SVD分解后的 U , Σ , V U,Σ,V U,Σ,V这三个矩阵呢?

如果将 A A A的转置和 A A A做矩阵乘法,那么会得到 n × n n×n n×n的一个方阵 A T A A^TA ATA。既然 A T A A^TA ATA是方阵,那么可以进行特征分解,得到的特征值和特征向量满足下式:
( A T A ) v i = λ i v i (A^TA)v_i=\lambda_i v_i (ATA)vi=λivi
这样可以得到矩阵 A T A A^TA ATA n n n个特征值和对应的 n n n个特征向量 v v v了。将 A T A A^TA ATA的所有特征向量张成一个 n × n n×n n×n的矩阵 V V V,即为SVD公式里面的 V V V矩阵了。一般将 V V V中的每个特征向量叫做 A A A的右奇异向量。

如果我们将A和A的转置做矩阵乘法,那么会得到 m × m m×m m×m的一个方阵 A A T AA^T AAT。既然 A A T AA^T AAT是方阵,那么可以进行特征分解,得到的特征值和特征向量满足下式:
( A A T ) u i = λ i u i (AA^T)u_i=\lambda_iu_i (AAT)ui=λiui
这样可以得到矩阵 A A T AA^T AAT n n n个特征值和对应的 m m m个特征向量 u u u了。将 A A T AA^T AAT的所有特征向量张成一个 m × m m×m m×m的矩阵 U U U,即为SVD公式里面的 U U U矩阵了。一般将 U U U中的每个特征向量叫做 A A A的左奇异向量。

U U U V V V都求出来了,现在就剩下奇异值矩阵 Σ \Sigma Σ 没有求出了。由于除了对 Σ \Sigma Σ 角线上是奇异值其他位置都是0,那只需要求出每个奇异值 σ \sigma σ 就可以了。
A = U Σ V T ⇒ A V = U Σ V T V ⇒ A V = U Σ ⇒ A v i = σ i u i ⇒ σ i = A v i / u i A=U\Sigma V^T \Rightarrow AV=U\Sigma V^TV \Rightarrow AV=U\Sigma \Rightarrow Av_i = \sigma_i u_i \Rightarrow \sigma_i = Av_i / u_i A=UΣVTAV=UΣVTVAV=UΣAvi=σiuiσi=Avi/ui
这样我们可以求出我们的每个奇异值,进而求出奇异值矩阵 Σ \Sigma Σ

A T A A^TA ATA的特征向量组成的就是我们SVD中的 V V V矩阵,而 A A T AA^{T} AAT的特征向量组成的就是我们SVD中的 U U U矩阵,这有什么根据吗?这个其实很容易证明,我们以 V V V矩阵的证明为例。
A = U Σ V T ⇒ A T = V Σ T U T ⇒ A T A = V Σ T U T U Σ V T = V Σ 2 V T A=U\Sigma V^T \Rightarrow A^T=V\Sigma^T U^T \Rightarrow A^TA = V\Sigma^T U^TU\Sigma V^T = V\Sigma^2V^T A=UΣVTAT=VΣTUTATA=VΣTUTUΣVT=VΣ2VT
上式证明使用了: U T U = I , Σ T Σ = Σ 2 U^TU=I, \Sigma^T\Sigma=\Sigma^2 UTU=I,ΣTΣ=Σ2。 可以看出 A T A A^TA ATA的特征向量组成的的确就是我们SVD中的 V V V矩阵。类似的方法可以得到 A A T AA^T AAT的特征向量组成的就是我们SVD中的 U U U矩阵。

特征值矩阵等于奇异值矩阵的平方,也就是说特征值和奇异值满足如下关系:
σ i = λ i \sigma_i = \sqrt{\lambda_i} σi=λi
通过求出 A T A A^{T}A ATA的特征值取平方根来求奇异值更加方便。

5.1.3 SVD的性质

  对于奇异值,它跟特征分解中的特征值类似,在奇异值矩阵中也是按照从大到小排列,而且奇异值的减少特别的快,在很多情况下,前10%甚至1%的奇异值的和就占了全部的奇异值之和的99%以上的比例。也就是说,可以用最大的 k k k个的奇异值和对应的左右奇异向量来近似描述矩阵。也就是说:
A m × n = U m × m Σ m × n V n × n T ≈ U m × k Σ k × k V k × n T A_{m \times n} = U_{m \times m}\Sigma_{m \times n} V^T_{n \times n} \approx U_{m \times k}\Sigma_{k \times k} V^T_{k \times n} Am×n=Um×mΣm×nVn×nTUm×kΣk×kVk×nT
  SVD可以用于PCA降维,来做数据压缩和去噪。也可以用于推荐算法,将用户和喜好对应的矩阵做特征分解,进而得到隐含的用户需求来做推荐。同时也可以用于NLP中的算法,比如潜在语义索引(LSI)。

5.1.4 SVD与PCA的关系

PCA的算法流程

求样本 x ( i ) x^{(i)} x(i) n ′ n' n维的主成分其实就是求样本集的协方差矩阵 X X T XX^T XXT的前 n ′ n' n个特征值对应特征向量矩阵 W W W,然后对于每个样本 x ( i ) x^{(i)} x(i),做如下变换 z ( i ) = W T x ( i ) z^{(i)}=W^Tx^{(i)} z(i)=WTx(i),即达到降维的PCA目的。

下面我们看看具体的算法流程。

输入 n n n维样本集 D = ( x ( 1 ) , x ( 2 ) , . . . , x ( m ) ) D=(x^{(1)}, x^{(2)},...,x^{(m)}) D=(x(1),x(2),...,x(m)),要降维到的维数 n ′ n' n.

输出:降维后的样本集 D ′ D′ D

  1. 对所有的样本进行中心化: x ( i ) = x ( i ) − 1 m ∑ j = 1 m x ( j ) x^{(i)} = x^{(i)} - \frac{1}{m}\sum\limits_{j=1}^{m} x^{(j)} x(i)=x(i)m1j=1mx(j)

  2. 计算样本的协方差矩阵 X X T XX^{T} XXT

  3. 对矩阵 X X T XX^{T} XXT进行特征值分解

4)取出最大的n’个特征值对应的特征向量 ( w 1 , w 2 , . . . , w n ′ ) (w_1,w_2,...,w_n′) (w1,w2,...,wn), 将所有的特征向量标准化后,组成特征向量矩阵 W W W

5)对样本集中的每一个样本 x ( i ) x^{(i)} x(i),转化为新的样本 z ( i ) = W T x ( i ) z^{(i)}=W^Tx^{(i)} z(i)=WTx(i)

  1. 得到输出样本集 D ′ = ( z ( 1 ) , z ( 2 ) , . . . , z ( m ) ) D' =(z^{(1)}, z^{(2)},...,z^{(m)}) D=(z(1),z(2),...,z(m))

有时候,我们不指定降维后的 n ′ n' n的值,而是换种方式,指定一个降维到的主成分比重阈值 t t t。这个阈值 t t t ( 0 , 1 ] (0,1] (0,1]之间。假如我们的n个特征值为 λ 1 ≥ λ 2 ≥ . . . ≥ λ n \lambda_1 \geq \lambda_2 \geq ... \geq \lambda_n λ1λ2...λn,则 n ′ n' n可以通过下式得到:
∑ i = 1 n ′ λ i ∑ i = 1 n λ i ≥ t \frac{\sum\limits_{i=1}^{n'}\lambda_i}{\sum\limits_{i=1}^{n}\lambda_i} \geq t i=1nλii=1nλit
SVD用于PCA

PCA仅仅使用了我们SVD的右奇异矩阵,没有使用左奇异矩阵,那么左奇异矩阵有什么用呢?

现有样本是 m × n m×n m×n的矩阵 X X X,如果我们通过SVD找到了矩阵 X X T XX^{T} XXT最大的 d d d个特征向量张成的 m × d m×d m×d维矩阵 U U U,则如果进行如下处理:
X d × n ′ = U d × m T X m × n X'_{d \times n} = U_{d \times m}^TX_{m \times n} Xd×n=Ud×mTXm×n
可得一个 d × n d×n d×n的矩阵 X ' X' X,和原来的 m × n m×n m×n维样本矩阵 X X X相比,行数从 m m m减到了 d d d,可见对行数进行了压缩。也就是说,左奇异矩阵可以用于行数的压缩。相对的,右奇异矩阵可以用于列数即特征维度的压缩,也就是PCA降维。

5.2 FunkSVD(LFM)

  2006年的Netflix Prize之后, Simon Funk公布了一个矩阵分解算法叫做Funk-SVD, 后来被 Netflix Prize 的冠军Koren称为Latent Factor Model(LFM)

  FunkSVD是在传统SVD面临计算效率问题时提出来的,既然将一个矩阵做SVD分解成3个矩阵很耗时,同时还面临稀疏的问题,那么能不能避开稀疏问题的同时只分解成两个矩阵呢?即现在期望我们的矩阵 M M M这样进行分解:
M m × n = P m × k T Q k × n M_{m \times n}=P_{m \times k}^TQ_{k \times n} Mm×n=Pm×kTQk×n

目标:让用户的评分和用矩阵乘积得到的评分残差尽可能的小,也就是说,可以用均方差作为损失函数,来寻找最终的 P P P Q Q Q

  对于某一个用户评分 m i j m_{ij} mij,如果用FunkSVD进行矩阵分解,则对应的表示为 q j T p i q_j^Tp_i qjTpi,采用均方差做为损失函数,则我们期望 ( m i j − q j T p i ) 2 (m_{ij}-q_j^Tp_i)^2 (mijqjTpi)2尽可能的小,如果考虑所有的物品和样本的组合,则我们期望最小化下式:
∑ i , j ( m i j − q j T p i ) 2 \sum\limits_{i,j}(m_{ij}-q_j^Tp_i)^2 i,j(mijqjTpi)2
只要能最小化上面的式子,并求出极值所对应的 p i , q j p_i, q_j pi,qj,则可以得到矩阵 P P P Q Q Q,那么对于任意矩阵 M M M任意一个空白评分的位置,我们可以通过 q j T p i q_j^Tp_i qjTpi计算预测评分。

在实际应用中,为了防止过拟合,会加入一个L2的正则化项,因此正式的FunkSVD的优化目标函数 J ( p , q ) J(p,q) J(p,q)是这样的:
a r g    m i n ⏟ p i , q j    ∑ i , j ( m i j − q j T p i ) 2 + λ ( ∣ ∣ p i ∣ ∣ 2 2 + ∣ ∣ q j ∣ ∣ 2 2 ) \underbrace{arg\;min}_{p_i,q_j}\;\sum\limits_{i,j}(m_{ij}-q_j^Tp_i)^2 + \lambda(||p_i||_2^2 + ||q_j||_2^2 ) pi,qj argmini,j(mijqjTpi)2+λ(∣∣pi22+∣∣qj22)
其中 λ \lambda λ 为正则化系数,需要调参。对于这个优化问题,一般通过梯度下降法来进行优化得到结果。

将上式分别对 p i , q j p_i, q_j pi,qj求导得:
∂ J ∂ p i = − 2 ( m i j − q j T p i ) q j + 2 λ p i ∂ J ∂ q j = − 2 ( m i j − q j T p i ) p i + 2 λ q j \begin{align} &\frac{\partial J}{\partial p_i} = -2(m_{ij}-q_j^Tp_i)q_j + 2\lambda p_i\\[2ex] & \frac{\partial J}{\partial q_j} = -2(m_{ij}-q_j^Tp_i)p_i + 2\lambda q_j \end{align} piJ=2(mijqjTpi)qj+2λpiqjJ=2(mijqjTpi)pi+2λqj
则在梯度下降法迭代时, p i , q j p_i, q_j pi,qj的迭代公式为:
p i = p i + α ( ( m i j − q j T p i ) q j − λ p i ) q j = q j + α ( ( m i j − q j T p i ) p i − λ q j ) \begin{align} & p_i = p_i + \alpha((m_{ij}-q_j^Tp_i)q_j - \lambda p_i)\\[2ex] & q_j =q_j + \alpha((m_{ij}-q_j^Tp_i)p_i - \lambda q_j) \end{align} pi=pi+α((mijqjTpi)qjλpi)qj=qj+α((mijqjTpi)piλqj)
通过迭代我们最终可以得到 P P P Q Q Q,进而用于推荐。

5.3 BiasSVD算法

BiasSVD算法是在FunkSVD算法的基础上考虑了用户和商品的偏好。用户有自己的偏好(Bias),比如乐观的用户打分偏高;商品也有自己的偏好(Bias),比如质量好的商品,打分偏高;BiasSVD算法将与个性化无关的部分,设置为偏好(Bias)部分。

假设评分系统平均分为 μ \mu μ,第i个用户的用户偏置项为 b i b_i bi ,而第 j j j 个物品的物品偏置项为 b j b_j bj,则加入了偏置项以后的优化目标函数 J ( p , q ) J(p,q) J(p,q) 如下:
a r g    m i n ⏟ p i , q j    ∑ i , j ( m i j − μ − b i − b j − q j T p i ) 2 + λ ( ∣ ∣ p i ∣ ∣ 2 2 + ∣ ∣ q j ∣ ∣ 2 2 + ∣ ∣ b i ∣ ∣ 2 2 + ∣ ∣ b j ∣ ∣ 2 2 ) \underbrace{arg\;min}_{p_i,q_j}\;\sum\limits_{i,j}(m_{ij}-\mu-b_i-b_j-q_j^Tp_i)^2 + \lambda(||p_i||_2^2 + ||q_j||_2^2 + ||b_i||_2^2 + ||b_j||_2^2) pi,qj argmini,j(mijμbibjqjTpi)2+λ(∣∣pi22+∣∣qj22+∣∣bi22+∣∣bj22)
优化目标也可以采用梯度下降法求解。 b i , b j b_i,b_j bi,bj一般可以初始设置为 0 0 0,然后参与迭代。 b i , b j b_i,b_j bi,bj迭代方法如下:
b i = b i + α ( m i j − μ − b i − b j − q j T p i − λ b i ) b j = b j + α ( m i j − μ − b i − b j − q j T p i − λ b j ) \begin{align} & b_i = b_i + \alpha(m_{ij}-\mu-b_i-b_j-q_j^Tp_i -\lambda b_i)\\[2ex] & b_j = b_j + \alpha(m_{ij}-\mu-b_i-b_j-q_j^Tp_i -\lambda b_j) \end{align} bi=bi+α(mijμbibjqjTpiλbi)bj=bj+α(mijμbibjqjTpiλbj)
通过迭代我们最终可以得到 P P P Q Q Q,进而用于推荐。

5.4 SVD++算法

SVD++算法在BiasSVD算法上进一步做了增强,这里它增加考虑用户的隐式反馈。

对于某一个用户 i i i,它提供了隐式反馈的物品集合定义为 N ( i ) N(i) N(i), 这个用户对某个物品 j j j对应的隐式反馈修正的评分值为 c i j c_{ij} cij, 那么该用户所有的评分修正值为 ∑ s ∈ N ( i ) c i s \sum\limits_{s \in N(i)}c_{is} sN(i)cis。一般我们将它表示为用 q s T y i q_s^Ty_i qsTyi形式,则加入了隐式反馈项以后的优化目标函数 J ( p , q ) J(p,q) J(p,q)如下:
a r g    m i n ⏟ p i , q j    ∑ i , j ( m i j − μ − b i − b j − q j T p i − q j T ∣ N ( i ) ∣ − 1 / 2 ∑ s ∈ N ( i ) q s ) 2 + λ ( ∣ ∣ p i ∣ ∣ 2 2 + ∣ ∣ q j ∣ ∣ 2 2 + ∣ ∣ b i ∣ ∣ 2 2 + ∣ ∣ b j ∣ ∣ 2 2 + ∑ s ∈ N ( i ) ∣ ∣ q s ∣ ∣ 2 2 ) \underbrace{arg\;min}_{p_i,q_j}\;\sum\limits_{i,j}(m_{ij}-\mu-b_i-b_j-q_j^Tp_i - q_j^T|N(i)|^{-1/2}\sum\limits_{s \in N(i)}q_{s})^2+ \lambda(||p_i||_2^2 + ||q_j||_2^2 + ||b_i||_2^2 + ||b_j||_2^2 + \sum\limits_{s \in N(i)}||q_{s}||_2^2) pi,qj argmini,j(mijμbibjqjTpiqjTN(i)1/2sN(i)qs)2+λ(∣∣pi22+∣∣qj22+∣∣bi22+∣∣bj22+sN(i)∣∣qs22)
其中,引入 ∣ N ( i ) ∣ − 1 / 2 |N(i)|^{-1/2} N(i)1/2是为了消除不同 ∣ N ( i ) ∣ |N(i)| N(i)个数引起的差异。式子够长的,不过需要考虑用户的隐式反馈时,使用SVD++还是不错的选择。

6.矩阵分解算法的优缺点

优点:

  1. 泛化能力强。一定程度上解决了数据稀疏的问题。

  2. 空间复杂度低。 仅仅存储用户和物品隐向量。空间复杂度有 n 2 n^2 n2 降低到 ( m + n ) ∗ k (m+n)*k (m+n)k

  3. 更好的扩展性和灵活性。 矩阵分解的最终产物是用户和物品隐向量, 这个深度学习的embedding思想不谋而合, 因此矩阵分解的结果非常便于与其他特征进行组合和拼接, 并可以与深度学习无缝结合。

缺点:

  1. 矩阵分解算法依然是只用到了评分矩阵, 没有考虑到用户特征, 物品特征和上下文特征, 这使得矩阵分解丧失了利用很多有效信息的机会。
  2. 在缺乏用户历史行为的时候, 无法进行有效的推荐。

本文仅仅做个人学习记录所用,不作为商业用途,谢谢理解。

参考:

1.https://www.cnblogs.com/pinard/p/6351319.html

2.https://alice1214.github.io/%E6%8E%A8%E8%8D%90%E7%AE%97%E6%B3%95/2020/07/08/%E6%8E%A8%E8%8D%90%E7%AE%97%E6%B3%95%E5%AD%A6%E4%B9%A0-%E4%BA%94-%E7%9F%A9%E9%98%B5%E5%88%86%E8%A7%A3/

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/423742.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

买车了

最近先后去试驾了比小鹏P7i、蔚来ET5、智己LS7、亚迪汉这几辆车&#xff0c;这四个品牌总共花了三天时间&#xff0c;也算是比较深度的试驾吧&#xff0c;静态和动态、前后排、主副驾都感受了一下。前面写了比亚迪汉的试驾体验&#xff0c;详细分析了它的优缺点&#xff1a;不愧…

Vue过滤器、自定义指令、组件

目录 一&#xff1a;生命周期 1.1 生命周期实例 1.2 生命周期函数&#xff08;引入&#xff09; 二&#xff1a;过滤器 三&#xff1a;自定义指令 四&#xff1a;组件 4.1 非单文件组件 4.2 组件的嵌套 4.3 单文件组件 模板 4.3.1 架构 4.3.2 不同版本的vue.JS 4…

ASRT语音识别系统部署及模型训练笔记

ASRT语音识别系统部署及模型训练笔记 前言 ASRT是一个中文语音识别系统&#xff0c;由AI柠檬博主开源在GitHub上。 GitHub地址&#xff1a;nl8590687/ASRT_SpeechRecognition 国内Gitee镜像地址&#xff1a;AI柠檬/ASRT_SpeechRecognition 文档地址&#xff1a;ASRT语音识…

ping telnet curl的使用方法和应用场景

文章目录一、区别二、使用方法pingtelnetcurl三、应用场景一、区别 ping命令基于ICMP协议&#xff0c;通过发送发送ICMP数据包&#xff0c;并查看对方是否有返回数据来检测网络是否连通&#xff0c;仅包含控制信息&#xff0c;不包含端口号; telnet是对服务器的远程登录&#…

全网火爆,Python接口自动化测试,从0到1分层封装框架撸码(带接口)

目录&#xff1a;导读前言一、Python编程入门到精通二、接口自动化项目实战三、Web自动化项目实战四、App自动化项目实战五、一线大厂简历六、测试开发DevOps体系七、常用自动化测试工具八、JMeter性能测试九、总结&#xff08;尾部小惊喜&#xff09;前言 随着行业内卷越来越…

3D开发工具HOOPS最新解析合集,助力实现web端高性能模型渲染

一、3D技术为创新提供强大助力 不管您想搭建桌面、WEB或者移动端APP应用&#xff0c;技术领先全球的HOOPS Platform组件都可以为您提供弹性的3D集成架构&#xff0c;同时&#xff0c;一批可信任的工业领域3D技术专家也将为您提供技术支持服务。 如果您的客户期望有一种在多个…

Docker 配置远程访问

Docker客户端通常通过Unix套接字在本地与守护程序通信 /var/run/docker.sock&#xff0c;或通过网络通过TCP套接字。 以下是启动时提供给Docker守护程序的选项的典型示例&#xff1a; # ps -ef |grep dockerd root 23438 1 0 00:41 ? 00:00:03 /usr/bin/dock…

Spring入门案例--IOC入门案例

IOC入门案例思路分析 (1)Spring是使用容器来管理bean对象的&#xff0c;那么管什么? 主要管理项目中所使用到的类对象&#xff0c;比如(Service和Dao) (2)如何将被管理的对象告知IOC容器? 使用配置文件 (3)被管理的对象交给IOC容器&#xff0c;要想从容器中获取对象&…

TCP协议详解

1.TCP的准备条件在古代的时候&#xff0c;古人们经常写书信进行交流&#xff0c;写书信的前提是你要知道这份信是要寄给谁在网络中&#xff0c;我们通过ip端口号找对目标对象&#xff0c;但是现在网站一般会对ip端口注册一个域名&#xff0c;所以我们一般就是对域名进行查找&am…

minikube安装与运行(阿里云环境运行)

说下为啥选择云环境&#xff0c;最开始在本地电脑上安装的minikube&#xff0c;但是由于国内的网络访问不了谷歌的镜像仓库&#xff0c;安装ingress-nginx或者其他插件时着实的恶心。要不翻墙&#xff0c;要不自己搭建个镜像仓库。最终决定用阿里云境外的节点&#xff0c;按小时…

Windows操作系统C盘快速扩容工具推荐

Windows 系统C 盘扩容教程 1️⃣前言 大家在使用电脑过程中&#xff0c;随着时间的推移&#xff0c;经常会发现C盘空间爆红的情况&#xff0c;主 要原因是电脑软件在使用过程中产生的缓存文件或者日志文件大部分都会存储在C盘&#xff0c;这样时间一久&#xff0c;C盘的存储空…

不联网新华字典

介绍 首页字典 更多 包含内容 内容对应Json数据文件百家姓baijiaxing.json曹操诗集caocao.json弟子规dizigui.json成语idiom.json论语lunyu.json纳兰性德诗集nalanshiji.json千家诗qianjiashi.json千字文qianziwen.json三字经-传统版sanzijing_ct.json三字经-新版sanzijing_x…

「STM32入门」TIM定时中断

定时器的简介 定时器可以对输入的时钟进行计数&#xff0c;并在计数值达到设定值时触发中断&#xff0c;在中断内可以执行中断事件不仅具备基本的定时中断功能&#xff0c;而且还包含内外时钟源选择&#xff0c;主从触发模式&#xff0c;输入捕获&#xff0c;输出捕获&#xff…

MySQL调优笔记——慢SQL优化记录

上周&#xff0c;项目出现线上问题&#xff0c;在这家公司做的是一个SAAS平台&#xff0c;总用户量大约10万人&#xff1b; 经过排查&#xff0c;发现是SQL问题&#xff0c;导致数据库响应慢&#xff0c;进而拖垮了整体服务&#xff1b; 通常&#xff0c;查询耗时较长的SQL涉…

我在windows10下,使用CMake gui 编译krita源码,CMake gui报错:LibMyPaint_DIR-NOTFOUND

系列文章目录 文章目录系列文章目录前言一、原因二、解决1.引入库前言 我在windows10下&#xff0c;使用CMake gui 编译krita源码 where is the source code:E:/krita-dev/krita where to build the binaries:E:/krita-dev/krita_camke current generator:MinGW Makefiles 分别…

ios证书申请流程

mac电脑-钥匙串-请求证书-得到CertificateSigningRequest 2.创建Identifiers &#xff08;1&#xff09; (2) (3) (4) 如要接推送等 勾&#xff1a;Push Notifications 如要生成universal links 勾&#xff1a;Associated Domains 3.创建Certificates 注意&#xff1a;需…

银行数字化转型导师坚鹏:《银行保险监管统计管理办法》

《银行保险监管统计管理办法》 ——“监”听则明 护航银行高质量发展课程背景&#xff1a; 很多金融机构存在以下问题&#xff1a; 不清楚《银行保险监管统计管理办法》出台背景&#xff1f; 不知道如何理解《银行保险监管统计管理办法》相关规定&#xff1f; 不清楚如何落…

UI设计师都在用这5个网站,赶紧马住~

本期推荐5个UI设计师常用的素材、学习网站&#xff0c;设计师们赶紧收藏~ 1、菜鸟图库 https://www.sucai999.com/searchlist/UIsheji----all-0-0.html?vNTYxMjky 菜鸟图库提供了超多免费设计素材&#xff0c;在这里你可以找到平面、UI、电商等设计类素材&#xff0c;还有大…

4.2和4.3、MAC地址、IP地址、端口

计算机网络等相关知识可以去小林coding进行巩固&#xff08;点击前往&#xff09; 4.2和4.3、MAC地址、IP地址、端口1.MAC地址的简介2.IP地址①IP地址简介②IP地址编址方式③A类IP地址④B类IP地址⑤C类IP地址⑥D类IP地址⑧子网掩码3.端口①简介②端口类型1.MAC地址的简介 网卡…

面试如何脱引而出?Redis字符串底层原理你掌握了吗

今天我们讲解字符串的底层原理&#xff0c;属于进阶内容&#xff0c;能回答出来可以秒杀80%的面试者。‍大家都知道Redis有5种基本数据类型&#xff0c;但是你知道每种数据类型对应的底层编码或者数据结构是什么样的吗&#xff1f;这在面试中是一个有区分度的问题&#xff0c;如…