【王树森推荐系统公开课】笔记05(矩阵补充、线上召回)

课程链接

1 矩阵补充(Matrix Completion)  

矩阵补充是向量召回最简单的一种方法,不过现在已经不太常用这种方法了。

1.1 矩阵补充模型 

        模型的输出是一个实数,是用户对物品兴趣的预估值。这个数越大,表示用户对物品越感兴趣。

        Embedding 层之间不共享参数。

1.2 训练

基本想法

  • 用户 embedding 参数矩阵记作 A。第 u 号用户对应矩阵第 u 列,记作向量 \alpha _u​。

  • 物品 embedding 参数矩阵记作 B。第 i 号物品对应矩阵第 i 列,记作向量 b_i​。

  • 内积 \left \langle \alpha _u,b_i \right \rangle 是第 u 号用户对第 i 号物品兴趣的预估值。

  • 训练模型的目的是学习矩阵 A 和 B,使得预估值拟合真实观测的兴趣分数。

数据集

图片中的文字内容如下:

  • 数据集:(用户ID物品ID,兴趣分数)的集合,记作 \Omega=\left \{ \left ( u,i,y \right ) \right \}

  • 数据集中的兴趣分数是系统记录的,比如:

    • 曝光但是没有点击 → 0 分

    • 点击、点赞、收藏、转发 → 各算 1 分

    • 分数最低是 0,最高是 4。

训练

  • 把用户ID、物品ID映射成向量。

    • 第 u 号用户 → 向量 au​。

    • 第 i 号物品 → 向量 bi​。

  • 求解优化问题,得到参数 A 和 B。

\min_{A, B} \sum_{(u, i, y) \in \Omega} \left( y - \langle \mathbf{a}_u, \mathbf{b}_i \rangle \right)^2.

  • (u, i, y):用户 u 对物品 i 的真实兴趣分数是 y。
  • \langle \mathbf{a}_u, \mathbf{b}_i \rangle:模型对兴趣分数的预估,反应第 u 号用户有多喜欢第 i 号物品。
  • y - \langle \mathbf{a}_u, \mathbf{b}_i \rangle:真实兴趣分数 y 与预估值之间的差,希望这个差越小越好。
  • \sum_{(u, i, y) \in \Omega}:对每一条记录的差的平方求和,作为优化的目标函数。
  • \min_{A, B}:对目标函数求最小化,优化的变量是矩阵 A 和 B

求最小化可以用随机梯度下降等算法,每次更新矩阵 A 和 B 的一列,这样就可以学出矩阵 A 和 B

1.3 为什么模型叫矩阵补充?

绿色位置表示曝光给用户的物品;灰色位置表示没有曝光。

        只要把物品曝光给用户,就知道用户对物品是否感兴趣。我们并不知道用户对没曝光的物品是否感兴趣。

        拿绿色位置的数据训练出模型,有了模型就可以预估出所有灰色位置的分数,也就是把矩阵的元素给补全,这就是为什么模型叫矩阵补充。

        把矩阵元素补全之后就可以做推荐。给定一个用户,选出用户对应的行中分数较高的物品推荐给该用户。

1.4 矩阵补充在实践中效果不好

  • 缺点1:仅用ID embedding,没利用物品、用户属性。

    • 物品属性:类别、关键词、地理位置、作者信息。

    • 用户属性:性别、年龄、地理定位、感兴趣的类目。

    • 双塔模型可以看做矩阵补充的升级版。

双塔模型(Two-Tower Model)是一种在深度学习领域,尤其是在推荐系统和信息检索等场景中常见的模型架构。这种模型的核心思想是将输入数据分成两个独立的部分,并通过两个独立的神经网络(即两个塔)分别处理这两个部分,然后在某个层次上将这两个部分数据的语义表示进行融合,以完成最终的任务。

  • 缺点2:负样本的选取方式不对。

    • 样本:用户—物品的二元组,记作 (u,i)

    • 正样本:曝光之后,有点击、交互。(正确的做法)

    • 负样本:曝光之后,没有点击、交互。(错误的做法)

  • 缺点3:做训练的方法不好。

    • 内积 \left \langle a_u,b_i \right \rangle不如余弦相似度。

    • 用平方损失(回归),不如用交叉熵损失(分类)。

  • 内积

    • 优点:直接计算两个向量的点积,简单直观。

    • 缺点:对向量长度敏感,可能导致结果不准确,尤其是当向量长度差异较大时。

  • 余弦相似度

    • 优点:只考虑向量的方向,忽略长度,适用于高维稀疏向量和对长度不敏感的场景。

    • 缺点:忽略了向量的长度信息,可能无法捕捉到向量之间的绝对差异。

2 线上服务

2.1 模型存储

做完训练之后,要把模型存储在正确的地方,便于做召回。

  1. 训练得到矩阵 AB

    A 的每一列对应一个用户。
    B 的每一列对应一个物品。
  2. 把矩阵 A 的列存储到 key-value 表。

    key 是用户 ID,value 是 A 的一列。
    给定用户 ID,返回一个向量(用户的 embedding)。
  3. 矩阵 B 的存储和索引比较复杂。

2.2 线上服务

在训练好模型,并且把 Embedding 向量做存储之后,可以开始做线上服务。

  1. 把用户 ID 作为 key,查询 key-value 表,得到该用户的向量,记作 a

  2. 最近邻查找:查找用户最有可能感兴趣的 k 个物品,作为召回结果。

    i 号物品的 embedding 向量记作 b_i​。
    内积 \left \langle a,b_i \right \rangle 是用户对第 i 号物品兴趣的预估。
    返回内积最大的 k 个物品。

这种最近邻查找有个严重的问题: 如果枚举所有物品,时间复杂度正比于物品数量。

如何加速最近邻查找,避免暴力枚举?

        有很多种算法加速最近邻查找,这些算法非常快,即使有几亿个物品最多也只需要几万次内积。这些算法的结果未必是最优的,但是不会比最优结果差多少。

3 近似最近邻查找(Approximate Nearest Neighbor Search)

3.1 支持最近邻查找的系统

  • 系统:Milvus、Faiss、HnswLib、等等。

  • 衡量最近邻的标准:

    • 欧式距离最小(L2距离

    • 向量内积最大(内积相似度

    • 向量夹角余弦最大(cosine相似度

目前推荐系统最常用的是余弦相似度,即最近邻是向量夹角最小的。

有些系统不支持余弦相似度,但这很好解决。如果把所有向量都做归一化,让它们的二范数全都等于1,那么内积就等于余弦相似度。

3.2 展示最近邻查找

         这是个散点图,每个点是物品的 Embedding 向量,Embedding 向量都是训练模型的时候计算出来的。

        右边的五角星表示一个用户的 Embedding 向量,记作 a。我们想要召回这个用户可能感兴趣的物品,这就需要计算向量 a 与所有点的相似度。如果用暴力枚举,计算量正比于点的数量,也就是物品的数量。

        想要减少最近邻查找的计算量,必须要避免暴力枚举。

3.3 一种加速最近邻查找的算法

        在做线上服务之前,先对数据做预处理,把数据划分成很多区域,如下图所示(以cosine相似度为标准。至于如何划分,取决于衡量最近邻的标准。

        划分之后,每个区域用一个向量表示。这些向量的长度都是1。划分区域之后,建立索引,把每个区域的向量作为 key,把区域中索引点的列表作为 value。

        假如有一个点,那么划分成一万个区域,索引上一个有一万个 key 值。每个向量是一个区域的 key 值,给定一个向量,可以快速取回这个区域内所有的点。有了这样一个索引,就可以在线上快速做召回了。

        在线上给用户做推荐,这个用户的 Embedding 向量记作 a,首先把向量 a 跟索引中这些向量做对比,计算它们的相似度。如果物品数量是几亿,索引中的向量数量也只有几万而已,这一步的计算开销不大。

        通过计算之后,发现下图所示向量与 a 最相似。通过索引找到这个区域内所有的点,每个点对应一个物品。

        接下来计算点 a 跟区域内所有点的相似度。如果一个有几亿个物品被划分到几万个区域,平均每个区域只有几万个点,所以这一步只需要计算几万次相似度,计算量也不大。

        假如我们想要找向量 a 最相似的三个点,也就是夹角最小的三个点,那么会找到下图所示的三个,对应三个物品。这三个物品就是最近邻查找的结果。

哪怕有几亿个物品,用这种近似算法做查找,也只需要计算几万次相似度,比暴力枚举快一万倍。

4 总结

  • 矩阵补充
    • 把物品ID、用户ID做 embedding,映射成向量。

    • 两个向量的内积 \left \langle a_u,b_i \right \rangle 作为用户 u 对物品 i 兴趣的预估。

    • \left \langle a_u,b_i \right \rangle 拟合真实观测的兴趣分数,学习模型的 embedding 层参数。

    • 矩阵补充模型有很多缺点,效果不好。

  • 线上召回

    • 把用户向量 a 作为 query,查找使得 \left \langle a,b_i \right \rangle 最大化的物品 i

    • 暴力枚举速度太慢。实践中用近似最近邻查找。

    • Milvus、Faiss、HnswLib 等向量数据库支持近似最近邻查找。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值