文章目录
一、矩阵分解
示例:针对协同过滤算法的头部效应比较明显、泛化能力较弱的问题,矩阵分解(或者叫隐语义模型)应运而生;矩阵分解在协同过滤算法中“共现矩阵”的基础上,加入了隐向量的概念,加强了模型处理稀疏矩阵的能力。
1.隐语义模型
隐语义模型最早在文本领域被提出,用于找到文本的隐含语义。在2006年, 被用于推荐中, 它的核心思想是通过隐含特征(latent factor)联系用户兴趣和物品(item), 基于用户的行为找出潜在的主题和分类, 然后对item进行自动聚类,划分到不同类别/主题(用户的兴趣)。
一个音乐评分的例子
假设每个用户都有自己的听歌偏好, 比如A喜欢带有小清新的, 吉他伴奏的, 王菲的歌曲,如果一首歌正好是王菲唱的, 并且是吉他伴奏的小清新, 那么就可以将这首歌推荐给这个用户。 也就是说是小清新, 吉他伴奏, 王菲这些元素连接起了用户和歌曲。 当然每个用户对不同的元素偏好不同, 每首歌包含的元素也不一样, 所以我们就希望找到下面的两个矩阵:
-
潜在因子—— 用户矩阵Q
这个矩阵表示不同用户对于不同元素的偏好程度, 1代表很喜欢, 0代表不喜欢, 比如下面这样: -
潜在因子——音乐矩阵P
表示每种音乐含有各种元素的成分, 比如下表中, 音乐A是一个偏小清新的音乐, 含有小清新的Latent Factor的成分是0.9, 重口味的成分是0.1, 优雅成分0.2…
利用上面的这两个矩阵, 我们就能得出张三对音乐A的喜欢程度:
张三对小清新的偏好 * 音乐A含有小清新的成分 + 张三对重口味的偏好 * 音乐A含有重口味的成分 + 张三对优雅的偏好 * 音乐A含有优雅的成分…,
按照这个计算方式, 每个用户对每首歌其实都可以得到这样的分数, 最后就得到了我们的评分矩阵:
矩阵分解模型其实就是在想办法基于这个评分矩阵去找到上面例子中的那两个矩阵, 也就是用户兴趣和物品的隐向量表达, 然后就把这个评分矩阵分解成Q和P两个矩阵乘积的形式, 这时候就可以基于这两个矩阵去预测某个用户对某个物品的评分了。 然后基于这个评分去进行推荐。这就是矩阵分解算法的原理。
2.矩阵分解算法的原理
在矩阵分解的算法框架下, 我们就可以通过分解协同过滤的共现矩阵来得到用户和物品的隐向量, 就是上面的用户矩阵Q和物品矩阵P, 这也是“矩阵分解”名字的由来。
矩阵分解算法将 m × n m\times n m×n维的共享矩阵 R R R分解成 m × k m \times k m×k维的用户矩阵 U U U和 k × n k \times n k×n维的物品矩阵 V V V相乘的形式。 其中 m m m是用户数量, n n n是物品数量, k k k是隐向量维度, 也就是隐含特征个数, 只不过这里的隐含特征变得不可解释了, 即我们不知道具体含义了, 要模型自己去学。 k k k的大小决定了隐向量表达能力的强弱, k k k越大, 表达信息就越强, 理解起来就是把用户的兴趣和物品的分类划分的越具体。
那么如果有了用户矩阵和物品矩阵的话, 我们就知道了如果想计算用户
u
u
u对物品
i
i
i的评分, 只需要
Preference
(
u
,
i
)
=
r
u
i
=
p
u
T
q
i
=
∑
f
=
1
F
p
u
,
k
q
k
,
i
\operatorname{Preference}(u, i)=r_{u i}=p_{u}^{T} q_{i}=\sum_{f=1}^{F} p_{u, k} q_{k,i}
Preference(u,i)=rui=puTqi=f=1∑Fpu,kqk,i
这里的
p
u
p_u
pu就是用户
u
u
u的隐向量, 就类似与上面的张三向量, 注意这是列向量,
q
i
q_i
qi是物品
i
i
i的隐向量, 就类似于上面的音乐A向量, 这个也是列向量, 所以才用了
p
u
T
q
i
p_{u}^{T} q_{i}
puTqi得到了一个数, 也就是用户的最终评分, 计算过程其实和上面例子中一样。 这里的
p
u
,
k
p_{u,k}
pu,k和
q
i
,
k
q_{i,k}
qi,k是模型的参数, 也正是我们想办法要计算的,
p
u
,
k
p_{u,k}
pu,k度量的是用户
u
u
u的兴趣和第
k
k
k个隐类的关系, 而
q
i
,
k
q_{i,k}
qi,k度量了第
k
k
k个隐类和物品
i
i
i之间的关系。
3.矩阵分解的求解
三种方法:特征值分解(用于方阵,不适于分解用户-物品矩阵)
奇异值分解(要求共现矩阵是稠密的,计算复杂度太高,故不适合)
梯度下降
3.1.梯度下降方法
评分预测值:
r
^
u
i
=
p
u
T
q
i
\hat{r}_{u i}=p_{u}^{T} q_{i}
r^ui=puTqi
误差:
e
u
i
=
r
u
i
−
r
^
u
i
e_{u i}=r_{u i}-\hat{r}_{u i}
eui=rui−r^ui
误差平方和:
SSE
=
1
2
∑
u
,
i
e
u
i
2
=
1
2
∑
u
,
i
(
r
u
i
−
∑
k
=
1
K
p
u
k
q
k
i
)
2
\operatorname{SSE}=\frac{1}{2} \sum_{u, i} e_{u i}^{2}=\frac{1}{2} \sum_{u, i}\left(r_{u i}-\sum_{k=1}^{K} p_{u k} q_{k i}\right)^{2}
SSE=21u,i∑eui2=21u,i∑(rui−k=1∑Kpukqki)2
目标函数:
min q ∗ , p ∗ 1 2 ∑ ( u , i ) ∈ K ( r u i − p u T q i ) 2 \min _{\boldsymbol{q}^{*}, \boldsymbol{p}^{*}}\frac{1}{2} \sum_{(u, i) \in K}\left(\boldsymbol{r}_{\mathrm{ui}}-p_{u}^{T} q_{i}\right)^{2} q∗,p∗min21(u,i)∈K∑(rui−puTqi)2
这里的
K
K
K表示所有用户评分样本的集合。
更新梯度:
p
u
,
k
=
p
u
,
k
−
η
(
−
e
u
i
q
k
,
i
)
=
p
u
,
k
+
η
e
u
i
q
k
,
i
q
k
,
i
=
q
k
,
i
−
η
(
−
e
u
i
p
u
,
k
)
=
q
k
,
i
+
η
e
u
i
p
u
,
k
p_{u, k}=p_{u,k}-\eta (-e_{ui}q_{k,i})=p_{u,k}+\eta e_{ui}q_{k,i} \\ q_{k, i}=q_{k, i}-\eta (-e_{ui}p_{u,k})=q_{k, i}+\eta e_{ui}p_{u,k}
pu,k=pu,k−η(−euiqk,i)=pu,k+ηeuiqk,iqk,i=qk,i−η(−euipu,k)=qk,i+ηeuipu,k
考虑其他的一些因素, 比如一个评分系统, 有些固有的属性和用户物品无关, 而用户也有些属性和物品无关, 物品也有些属性和用户无关。 为了消除用户和物品打分的偏差, 预测公式修改为如下:
r
^
u
i
=
μ
+
b
u
+
b
i
+
p
u
T
⋅
q
i
\hat{r}_{u i}=\mu+b_{u}+b_{i}+p_{u}^{T} \cdot q_{i}
r^ui=μ+bu+bi+puT⋅qi
这个预测公式加入了3项偏置
μ
,
b
u
,
b
i
\mu,b_u,b_i
μ,bu,bi, 作用如下:
- μ \mu μ: 训练集中所有记录的评分的全局平均数。 在不同网站中, 因为网站定位和销售物品不同, 网站的整体评分分布也会显示差异。 比如有的网站中用户就喜欢打高分, 有的网站中用户就喜欢打低分。 而全局平均数可以表示网站本身对用户评分的影响。
- b u b_u bu: 用户偏差系数, 可以使用用户 u u u给出的所有评分的均值, 也可以当做训练参数。 这一项表示了用户的评分习惯中和物品没有关系的那种因素。 比如有些用户比较苛刻, 对什么东西要求很高, 那么他评分就会偏低, 而有些用户比较宽容, 对什么东西都觉得不错, 那么评分就偏高
- b i b_i bi: 物品偏差系数, 可以使用物品 i i i收到的所有评分的均值, 也可以当做训练参数。 这一项表示了物品接受的评分中和用户没有关系的因素。 比如有些物品本身质量就很高, 因此获得的评分相对比较高, 有的物品本身质量很差, 因此获得的评分相对较低。
加了用户和物品的打分偏差之后, 矩阵分解得到的隐向量更能反映不同用户对不同物品的“真实”态度差异, 也就更容易捕捉评价数据中有价值的信息, 从而避免推荐结果有偏。 注意此时的
S
S
E
SSE
SSE会发生变化:
SSE
=
1
2
∑
u
,
i
e
u
i
2
+
1
2
λ
∑
u
∣
p
u
∣
2
+
1
2
λ
∑
i
∣
q
i
∣
2
+
1
2
λ
∑
u
b
u
2
+
1
2
λ
∑
u
b
i
2
=
1
2
∑
u
,
i
(
r
u
i
−
μ
−
b
u
−
b
i
−
∑
k
=
1
K
p
u
k
q
k
i
)
2
+
1
2
λ
∑
u
∣
p
u
∣
2
+
1
2
λ
∑
i
∣
q
i
∣
2
+
1
2
λ
∑
u
b
u
2
+
1
2
λ
∑
u
b
i
2
\begin{array}{l} \operatorname{SSE}=\frac{1}{2} \sum_{u, i} e_{u i}^{2}+\frac{1}{2} \lambda \sum_{u}\left|\boldsymbol{p}_{u}\right|^{2}+\frac{1}{2} \lambda \sum_{i}\left|\boldsymbol{q}_{i}\right|^{2}+\frac{1}{2} \lambda \sum_{u} \boldsymbol{b}_{u}^{2}+\frac{1}{2} \lambda \sum_{u} \boldsymbol{b}_{i}^{2} \\ =\frac{1}{2} \sum_{u, i}\left(\boldsymbol{r}_{u i}-\boldsymbol{\mu}-\boldsymbol{b}_{u}-\boldsymbol{b}_{i}-\sum_{k=1}^{K} \boldsymbol{p}_{u k} \boldsymbol{q}_{k i}\right)^{2}+\frac{1}{2} \lambda \sum_{u}\left|\boldsymbol{p}_{u}\right|^{2}+\frac{1}{2} \lambda \sum_{i}\left|\boldsymbol{q}_{i}\right|^{2}+\frac{\mathbf{1}}{2} \lambda \sum_{u} \boldsymbol{b}_{u}^{2}+\frac{1}{2} \lambda \sum_{u} \boldsymbol{b}_{i}^{2} \end{array}
SSE=21∑u,ieui2+21λ∑u∣pu∣2+21λ∑i∣qi∣2+21λ∑ubu2+21λ∑ubi2=21∑u,i(rui−μ−bu−bi−∑k=1Kpukqki)2+21λ∑u∣pu∣2+21λ∑i∣qi∣2+21λ∑ubu2+21λ∑ubi2
此时如果把
b
u
b_u
bu和
b
i
b_i
bi当做训练参数的话, 那么它俩的梯度是:
∂
∂
b
u
S
S
E
=
−
e
u
i
+
λ
b
u
∂
∂
b
i
S
S
E
=
−
e
u
i
+
λ
b
i
\frac{\partial}{\partial b_{u}} S S E=-e_{u i}+\lambda b_{u} \\ \frac{\partial}{\partial b_{i}} S S E=-e_{u i}+\lambda b_{i}
∂bu∂SSE=−eui+λbu∂bi∂SSE=−eui+λbi
更新公式为:
b
u
=
b
u
+
η
(
e
u
i
−
λ
b
u
)
b
i
=
b
i
+
η
(
e
u
i
−
λ
b
i
)
\begin{aligned} \boldsymbol{b}_{u}&=\boldsymbol{b}_{\boldsymbol{u}}+\boldsymbol{\eta}\left(\boldsymbol{e}_{u i}-\lambda \boldsymbol{b}_{\boldsymbol{u}}\right) \\ \boldsymbol{b}_{\boldsymbol{i}} &=\boldsymbol{b}_{\boldsymbol{i}}+\boldsymbol{\eta}\left(\boldsymbol{e}_{\boldsymbol{u} i}-\lambda \boldsymbol{b}_{\boldsymbol{i}}\right) \end{aligned}
bubi=bu+η(eui−λbu)=bi+η(eui−λbi)
而对于
p
u
,
k
p_{u,k}
pu,k和
p
k
,
i
p_{k,i}
pk,i, 导数没有变化, 更新公式也没有变化。
4.矩阵分解的优缺点
4.1.优点
- 泛化能力强: 一定程度上解决了稀疏问题
- 空间复杂度低: 由于用户和物品都用隐向量的形式存放, 少了用户和物品相似度矩阵, 空间复杂度由 n 2 n^2 n2降到了 ( n + m ) ∗ f (n+m)*f (n+m)∗f
- 更好的扩展性和灵活性:矩阵分解的最终产物是用户和物品隐向量, 这个深度学习的embedding思想不谋而合, 因此矩阵分解的结果非常便于与其他特征进行组合和拼接, 并可以与深度学习无缝结合。
4.2.缺点
只用到了评分矩阵, 没有考虑到用户特征, 物品特征和上下文特征, 这使得矩阵分解丧失了利用很多有效信息的机会, 同时在缺乏用户历史行为的时候, 无法进行有效的推荐。
5.FM模型–隐向量特征交叉
5.1.二阶交叉项的考虑及改进
目标函数由原来的
y
=
w
0
+
∑
i
=
1
n
w
i
x
i
y = w_0+\sum_{i=1}^nw_ix_i
y=w0+i=1∑nwixi
变为
y
=
w
0
+
∑
i
=
1
n
w
i
x
i
+
∑
i
=
1
n
−
1
∑
i
+
1
n
w
i
j
x
i
x
j
y = w_0+\sum_{i=1}^nw_ix_i+\sum_{i=1}^{n-1}\sum_{i+1}^nw_{ij}x_ix_j
y=w0+i=1∑nwixi+i=1∑n−1i+1∑nwijxixj
但这个式子有一个问题,只有当
x
i
x_i
xi与
x
j
x_j
xj均不为0时这个二阶交叉项才会生效
FM模型的优化函数:
y
=
w
0
+
∑
i
=
1
n
w
i
x
i
+
∑
i
=
1
n
∑
i
+
1
n
<
v
i
,
v
j
>
x
i
x
j
y = w_0+\sum_{i=1}^nw_ix_i+\sum_{i=1}^{n}\sum_{i+1}^n\lt v_i,v_j\gt x_ix_j
y=w0+i=1∑nwixi+i=1∑ni+1∑n<vi,vj>xixj
w
i
j
w_{ij}
wij替换成
<
v
i
,
v
j
>
\lt v_i,v_j\gt
<vi,vj>,实质上就是给每个
x
i
x_i
xi计算一个embedding,然后将两个向量之间的embedding做内积得到之前所谓的
w
i
j
w_{ij}
wij好处就是这个模型泛化能力强 ,即使两个特征之前从未在训练集中同时出现,我们也不至于像之前一样训练不出
w
i
j
w_{ij}
wij,事实上只需要
x
i
x_i
xi和其他的
x
k
x_k
xk同时出现过就可以计算出
x
i
x_i
xi的
embedding!
5.2.FM的优点
- FM模型中二次项的参数数量减少为 $kn $个,远少于多项式模型的参数数量,降低了训练开销。
- 降低了对数据稀疏性的要求。
- FM虽然丢失了某些具体特征组合的精确记忆能力,但是泛化能力大大提高。
5.3.FM模型的应用
最直接的想法就是直接把FM得到的结果放进sigmoid中输出一个概率值,由此做CTR预估,事实上我们也可以做召回。
由于FM模型是利用两个特征的Embedding做内积得到二阶特征交叉的权重,那么我们可以将训练好的FM特征取出离线存好,之后用来做KNN向量检索。
工业应用的具体操作步骤:
- 离线训练好FM模型(学习目标可以是CTR)
- 将训练好的FM模型Embedding取出
- 将每个uid对应的Embedding做avg pooling(平均)形成该用户最终的Embedding,item也做同样的操作
- 将所有的Embedding向量放入Faiss等
- 线上uid发出请求,取出对应的user embedding,进行检索召回