学习本教程的先决条件
尽管我会尽量减少数学术语的使用,但本文希望读者熟悉一些概念,如矩阵分解、嵌入空间以及基本的机器学习术语。这篇文章并不是推荐系统的介绍,而是对它们的增量变体的介绍。在任何情况下,本文的主要受众是机器学习和推荐系统领域的初学者。
简介
开始一个机器学习项目,数据科学家收集数据,对其进行处理,训练模型并将其部署到生产中。当模型的性能开始恶化时,数据科学家通常会从头开始重复这个循环。在这个时候,他们才有新的数据示例来对模型进行改进以提高其性能。然而,这通常是一种适得其反的做法,其效率也很低下,特别在那些根据当前数据做出的决策至关重要的业务领域来说尤其如此。
现在,进入推荐系统的世界吧,在这里,用户的偏好经常会随着季节、预算、时尚趋势等发生变化。此外,客户数量和库存造成了所谓的冷启动问题,即系统没有足够的信息使消费者与产品或服务相匹配。推荐系统在理想情况下应该适应这些变化,改进其模型以适应当前的状态,同时要对数据进行一次传递。这就是渐进式学习的理念。
在本文中,我们将探索在实践中将增量学习的思想应用到推荐系统中。我们使用一个基于 Pytorch 的 Python 库 CF Step,重现了 João Vinagre 等人发表的论文「Fast incremental matrix factorization for recommendation with positive-only feedback」中的结果。接下来,我们将通过应用几个技巧来实现更高的目标。
快速增量矩阵分解
我们将要实现的算法使用隐式的、仅为正的反馈。让我们试着解开这两个关键字的神秘面纱。
隐式反馈意味着用户从来没有对他们交互的项目表达过直接的意见,比如评级。隐式反馈的一个例子是,一个顾客买了多少次某个产品,或者花了多少分钟看了某个电影。顾客购买的产品或使用的服务越多,我们就越有信心认为,这是一种偏好。仅为正的反馈是一个与隐式反馈一起使用的术语。这是因为,在隐式反馈的情况下,我们很难知道是什么构成了消极互动。用户不与项目交互并不意味着什么,想象一下超市里的消费者,如果他们尚未购买特定产品,我们无法确定原因。
返回到我们的实现,仅为正的反馈意味着用户项交互矩阵 R 只包含布尔值,其中正值表示喜欢,负值被视为不确定。这个假设有两个主要的含义:R 的稀疏性是会保持的,因为在训练过程中只使用了正反馈;对于任何用户项交互,负值都是完美的推荐候选者。
算法与方法
现在让我们更仔细地看一下本文中提出的增量随机梯度下降(ISGD)算法。
ISGD——增量 SGD
我们拥有的数据是元组或用户项交互数据。记住,这些都是积极的交互。算法的输入是三个数字:feat (用户或项目嵌入空间的维数)、λ(正则化系数)和 η(学习速率)。算法的输出是两个嵌入矩阵:A 表示用户,B 表示项目。这些矩阵的维数是 A 的 number_of_users x feat 和 B 的 number_of_items x feat。然后我们有几个不同的步骤:
- 检查活跃用户是否是已知的。如果不是,则创建一个具有随机潜在特征的新用户,该用户从均值为 0、标准差为 1 的正态分布中提取。对活动项执行相同的操作。
- 计算损失。因为我们只需要处理积极的反馈,所以目标总为 1。因此,我们只需要从 1 中减去我们的预测值。
- 使用通用规则更新活跃用户的潜在特征(用户嵌入矩阵中的参数)。对活动项执行相同的操作。
- 转到下一个数据点。这样,我们可以处理任意长度的数据流。
实现与评估
对于这个实现,我们将使用 Python 库 CF Step 和众所周知的 Movielens 数据集(https://grouplens.org/datasets/movielens/ )。CF Step 是一个开源库,用 Python 编写并在 Pytorch 上构建,它支持增量学习推荐系统的快速实现。该库是欧洲研究项目 CloudDBAppliance 的副产品。你可以通过运行以下命令轻松安装库:
代码语言:javascript复制pip install cf-step
接下来,下载 movielens 数据集,并将 ratings.dat 文件提取在一个方便的目录下,例如 Linux 中的 tmp 文件夹。对于这个实现,我们只需要这个文件。其余文件(users.dat 和 movies.dat)包含用户和电影的元数据。我们将使用 pandas 加载内存中的文件:
如你所见,我们将用户和电影 ID 转换为类别,以便提取类别代码。现在,我们不必为嵌入矩阵的生成创建单独的词汇表。我们只需要使用用户和电影编码,而不是 ID。最后,我们总是通过这个数据帧在代码和 ID 之间建立连接,以找到原始用户和电影。现在,让我们看看我们正在处理的数据中的不重复的用户和电影的数量。
如果我们打印这些数字,我们将看到有 6040 个用户和 3706 部电影。接下来,我们将按时间戳对数据进行排序,以模拟事件流。
正如我们所讨论的,该算法只支持正反馈。因此,我们将把 5 分作为正反馈,并放弃其他任何评分。我们希望用 1 表示喜欢,用 0 表示不喜欢,并创建一个名为 preference 的新列来保留它们。然后,我们筛选出 preference == 1 的数据项。
接下来,让我们初始化我们的模型。为此,我们需要一个模型架构、一个目标函数(即损失函数)和一个优化器。我们将使用 SimpleCF 网络作为模型架构,这是 CF Step 提供的内置神经网络架构。对于目标函数,我们将使用一个简单的 lambda 函数,它接受一个预测和一个目标,并从目标减去预测。在我们的例子中,目标总是 1。对于优化器,我们将使用 Pytorch 的 SGD 来实现。我们选择的因子有 128 个,学习速率是 0.06。现在我们准备初始化 Step 模型。
评估方法如下:
- 通过在前 20% 的数据上对模型进行训练来引导它。
- 模拟数据流,并使用 recall@k 作为度量来评估模型的性能。
- 如果用户是已知的,则进行预测并计算此预测的 recall@kf。然后,使用这个用户项交互,递增地训练算法。
- 如果用户是未知的,只需使用此用户项交互以增量方式训练算法。
为此,让我们获取前 20% 的数据,创建数据加载器并批量拟合模型。
然后,我们得到剩余的数据并创建一个不同的数据集。
最后,模拟流并使用 recall@10 评估模型。这一步在 GPU 上需要 5 到 6 分钟。
我们可以使用下面的代码可视化我们的训练结果。为此,我们将使用一个 5K 滑窗的移动平均值,这和他们在论文中的做法是一样的。我们可以看到,这个图和 movielens 数据集的呈现结果类似。要保存模型,请使用 model.save() 内置方法并传递有效路径。
结论
在这篇文章中,我们提出了增量学习在推荐系统中的重要性,并重现了 João Vinagre 等人发表的论文「Fast incremental matrix factorization for recommendation with positive-only feedback」中的结果。我们介绍了 Python 的 CF Step 库,这是一个开源库,它支持增量学习推荐系统的快速实现。接下来,我们将进一步讨论这个问题,并尝试提高算法的准确性。
via:https://towardsdatascience.com/building-an-incremental-recommender-system-8836e30afaef
封面图来源:https://pixabay.com/images/id-3240007/