在 TensorFlow 中构建推荐系统:概览

本文是由多篇文章组成的系列教程中的概览篇,该系列教程介绍如何在 Google Cloud Platform (GCP) 中使用 TensorFlowAI Platform 实现实推荐系统。

这篇概览文章包含以下内容:

  • 概述基于矩阵因式分解的推荐系统理论。
  • 介绍用于执行矩阵因式分解的加权交替最小二乘 (WALS) 算法。
  • 概述一系列为在 GCP 上实现推荐系统提供分步指南的教程。

本教程中的推荐系统使用加权交替最小二乘 (WALS) 算法。WALS 随附在 TensorFlow 代码库的 contrib.factorization 程序包中,用于对大型用户和项目评分矩阵进行因式分解。

本系列教程

本概述附带的教程包括以下内容:

建议的背景理论

本文概述了基于矩阵因式分解的协同过滤应用于推荐系统时的背景理论。将对以下主题进行深入介绍,并提供一些链接以供深入阅读:

  • 协同过滤。什么是协同过滤?如何使用从中获得的见解?
  • 矩阵因式分解。什么是评分矩阵?什么是潜在因子?如何用数学方法转换评分矩阵以对其进行解释?
  • 用于矩阵因式分解的 WALS 方法。如何使用 WALS 方法执行矩阵因式分解?

用于推荐系统的协同过滤

协同过滤技术是用于生成用户推荐的有效方法。协同过滤仅依赖于观察到的用户行为来进行推荐,不需要配置文件数据或内容访问。

该技术基于以下观察结果:

  • 以类似方式(例如,购买相同的产品或查看相同的文章)与项目交互的用户拥有一个或多个相同的隐藏偏好。
  • 拥有共同偏好的用户可能会以相同的方式响应相同的项目。

通过结合这些基本观察结果,推荐引擎可以在无需确定用户共同偏好的确切性质的情况下运行。只需要该偏好存在且有意义。基本假设是,类似的用户行为反映了类似的基本偏好,推荐引擎从而可以相应地进行推荐。

例如,假设用户 1 已查看 A、B、C、D、E 和 F 项。用户 2 已查看 A、B、D、E 和 F 项,但未查看 C 项。由于两个用户都查看了相同的六项中的五项,因此他们可能拥有一些共同的基本偏好。用户 1 喜欢 C 项,如果用户 2 知道 C 项的存在,可能也会喜欢。推荐引擎可在这种情况下发挥作用:它将 C 项告知用户 2,从而引起用户的兴趣。

用于协同过滤的矩阵因式分解

协同过滤问题可以使用矩阵因式分解来解决。假设您有一个矩阵,其中包含用户 ID 及其与您的产品的交互信息。每行对应一个唯一用户,每列对应一个项目。项目可以是目录、文章或视频中的产品。矩阵中的每个条目都会捕获用户对单个项目的评分或偏好。评分可以是显式的,由用户反馈直接生成,也可以是隐式的,基于用户的购买或与文章或视频交互所花费的时间。

如果用户从未对某项进行过评分,也未对其显示出任何隐含的兴趣,则该矩阵条目为零。图 1 显示了 MovieLens 评分矩阵的表示法。

MovieLens 评分矩阵
图 1. MovieLens 评分矩阵

MovieLens 数据集中的评分,范围为 1 到 5。空评分条目的值为 0,表示给定用户未对该项进行评分。

定义矩阵因式分解方法

评分矩阵包含矩阵 R,其中条目 \(r_{ij}\) 是用户 \(i\) 对项目 \(j\) 的评分。对于许多互联网应用,这些矩阵很大,拥有数百万用户和数百万种不同的项目。它们也很稀疏,这意味着每个用户通常只对少量项目(相对于整个数据集)进行评分、查看或购买。绝大多数矩阵条目(通常大于 99%)为零。

矩阵因式分解方法假设所有项目都有一组共同的属性,而项目对这些属性的表达程度不同。此外,矩阵因式分解方法假定每个用户对这些属性都有自己的表达,与项目无关。通过这种方式,用户的项目评分可以通过将用户的每个属性的强度相加来近似计算得出,权重由项目表达该属性的程度决定。这些属性有时被称为隐藏或潜在因子。

直观上,很容易看出这些假设的潜在因子确实存在。就电影而言,很明显,许多用户更喜欢某些类型、演员或导演。这些类别代表潜在因子,虽然显而易见,但仍然非常有用。例如,类型偏好会体现在用户倾向于喜欢某些电影,并且具有类似类型偏好的人可能会喜欢类似的电影。协同过滤的矩阵因式分解方法的大部分功能源于以下事实:不必知道可能包括给定用户偏好的所有类型、演员或其他类别的数量。该方法只假设它们的数量是任意的。

转换矩阵以表示潜在因子

为了将存在的潜在因子转化为评分矩阵,您可以执行以下操作:对于一组大小为 u 的用户 U 和大小为 i 的项目 I,选择任意数量 k 的潜在因子并将大矩阵 R 因式分解为两个更小的矩阵 X(“行因子”)和 Y(“列因子”)。矩阵 X 的维度为 u × k,并且矩阵 Y 的维度为 k × i。如图 2 所示。

用行和列因子近似计算评分矩阵
图 2. 用行和列因子近似计算评分矩阵

在线性代数中,这称为低阶近似。您可以将此过程视为将 R 中的稀疏信息压缩到更低维的空间 u × kk × i。低阶矩阵 XY 相乘时获得的矩阵 R' 表示 R 的近似值。

在此 k 维空间中,每个用户都由一个矢量向量表示,并且 X 中的每行 \( \mathbf{x}_{u}\) 都对应于用户对这些 k 因子的偏好强度。同样,在此 k 维空间中,由矢量表示的每个项目在 Y 中都有一列 \(\mathbf{y}_{i}\),对应于该项目的相同 k 因子表达式。

要计算用户 u 对项目 i 的评分,需要取两个矢量的点积:

$$ r_{ui} = \mathbf{x}^{T}_{u} \cdot \mathbf{y}_{i} $$

该乘积是实数 \(r_{ui}\),并且表示用户 u 对项目 i 的评分的近似值或预测(用机器学习术语来表述)。相关说明见图 3。

根据行和列因子计算预测评分
图 3. 根据行和列因子计算预测评分

您可以定义损失函数来衡量近似值的准确度,方法如下:

$$ L = \sum_{u,i}(r_{ui} - \mathbf{x}^{T}_{u} \cdot \mathbf{y}_{i})^{2} $$

此公式会执行以下操作:针对所有用户和项目的近似评分 \(\mathbf{x}^T_{u} \cdot \mathbf{y}_{i}\) 与训练集 \(r_{ui}\) 中实际评分之间的平方差求和。

常见做法是将正则化项添加到此损失函数中,以防止出现过拟合。为行和列因子添加 L2 正则化项可得到以下结果:

$$ L = \sum_{u,i}(r_{ui} - \mathbf{x}^{T}_{u} \cdot \mathbf{y}_{i})^{2} + \lambda\sum_{u}\left\lVert\mathbf{x}_{u}\right\rVert^{2} + \lambda\sum_{i}\left\lVert\mathbf{y}_{i}\right\rVert^{2} $$

此处 \(\lambda \) 是一个正则化常量(模型的超参数之一),我们将在本系列教程的第 2 篇中进行讨论。

WALS 矩阵因式分解方法

本部分讨论两种矩阵因式分解方法。

交替最小二乘法

矩阵因式分解的交替最小二乘法是用于确定最近似于 R 的最佳因子 XY 的迭代方法。在每次迭代中,其中一个行或列因子保持固定,而另一个则通过最小化损失函数(相对于另一个因子)计算得出。

首先,从行因子开始:

  1. 将列因子设置为常量值。
  2. 根据行因子得出损失函数的导数。
  3. 将等式设置为零。
$$ \frac{\partial L}{\partial \mathbf{x}_{u}} = -2\sum_{i}(r_{ui} - \mathbf{x}^{T}_{u} \cdot \mathbf{y}_{i})\mathbf{y}^{T}_{i} + 2\lambda\mathbf{x}^{T}_{u} $$
$$ 0 = -(\mathbf{r}_{u} - \mathbf{x}^{T}_{u}Y^{T})Y + \lambda\mathbf{x}^{T}_{u} $$
$$ \mathbf{x}^{T}_{u}(Y^{T}Y + \lambda{I}) = \mathbf{r}_{u}Y $$
$$ \mathbf{x}^{T}_{u} = \mathbf{r}_{u}Y(Y^{T}Y + \lambda{I})^{-1} $$

迭代过程中,保持已求解的行因子不变,求解列因子的类似方程。交替行和列因子,重复迭代过程直到收敛,这通常发生在小型 (< 20) 迭代内,即使对于由数千万行或列组成的极大型矩阵也是如此。

加权交替最小二乘 (WALS) 方法

该算法的加权版本为矩阵中零或未观察到的条目和的非零条目引入了不同的权重:

$$ L^{w} = \mathbf{W} \cdot \sum_{u,i}(r_{ui} - \mathbf{x}^{T}_{u} \cdot \mathbf{y}_{i})^{2} $$

在此等式中:

\(w_{ui} = \omega_{0}\) 针对评分矩阵中的零(未观察到的)条目,和
\(w_{ui} = \omega_{0} + f(c_{i})\) 针对观察到的条目,其中
\(c_{i} = \sum_{u,i}1 \text{ if } r_{ui} > 0\) i 列的非零条目数之和

权重按行中非零条目的总和进行调节,以归一化已对其他数量的项目进行评分的用户的权重。

此类加权可实现更灵活的用户偏好模型,并生成比未加权版本更好的经验结果(如需了解详情,请参阅隐式反馈数据集的协同过滤一文)。函数 \(f\) 会根据数据集以及评分是显式还是隐式而有所不同。

MovieLens 数据集包含显式评分。在此情况下,\(f\) 的较好选择是对观察到的条目进行线性加权:

\(f = \omega_{k}c_{i}\) 其中 \(\omega_{k}\) 是观察到的权重。

对于与动态事件相关的隐式评分,其中每个评分对应于观看某视频、阅读某文章或查看某网页的次数,评分本身可能由于用户行为而呈指数分布。当用户点击某页面或视频然后又快速离开时,将会产生许多低值评分。当用户阅读整篇文章、观看整个视频或多次观看某一既定节目时,将会产生数量较少但分值较高的隐式评分。在此情况下,合适的 \(f\) 是对观察到的评分进行加权,以解释此分布:

\(f = \left(\frac{1}{c_{i}}\right)^{e}\) 其中 \(e\) 是特征权重指数。

比较 WALS 与其他技术

许多矩阵因式分解技术可用于协同过滤,包括 SVD随机梯度下降法。在某些情况下,这些技术可以提供比 WALS 更好的降秩近似值。本文不讨论不同协同过滤方法优缺点的比较,但值得注意的是 WALS 具有以下优点:

  • WALS 中使用的权重使其适用于隐式评分,但 WALS 也可以应用于显式评分数据集,例如 MovieLens
  • WALS 包含算法优化,可以轻松合并权重并高效计算行和列因子更新。如需了解详情,请参阅隐藏反馈数据集的协同过滤一文。这些优化内置于 WALS TensorFlow 代码库中。
  • 创建算法的分布式版本相对简单。分布式版本可以处理具有数亿行的极大型矩阵。本文不讨论 WALS 的分布式版本。

后续步骤

开始学习本系列中的教程:

此页内容是否有用?请给出您的反馈和评价:

发送以下问题的反馈:

此网页
Solutions