视频

了解更多
本教程将帮助您使用基于内容的过滤和向量相似性搜索,为电子商务系统构建实时产品推荐系统。请跟随学习基本步骤和其工作原理。
推荐系统对于大多数在线业务,特别是对于 电子商务网站 来说,是一项重要的技术。它们是产生良好转化和维护客户忠诚度的关键要素。
推荐系统通常会根据用户的个人资料和偏好,并通过观察他们的行为(例如购买、喜欢或查看商品)来向用户展示商品。
构建一个现代电子商务网站的推荐系统涉及诸多挑战。这仅是需要考虑的一部分问题
随着这些需求的演变,构建推荐系统的方法也需要随之发展。在这篇博客文章中,我们将向您展示如何利用最新的 向量搜索技术 ,根据用户定义的过滤器构建实时产品推荐系统。该工具集包括 Redis 和 DocArray,但无论您使用何种工具,这种方法都适用。
与任何其他计算问题一样,构建推荐系统有多种方法和支持工具,它们包括
本篇博客文章重点介绍如何改进基于内容的过滤方法。如果您是该领域的新手,建议您先阅读 Google 的概述,了解基于内容的过滤。
在实现基于内容的过滤时,有两个重要考虑因素
首先,当您将用户和商品建模为特征向量时,利用数据的各种模态非常重要。简单依赖关键词或一组人工设计的特征可能无法有效表示复杂数据。
这就是最先进的 AI 模型重要的原因,因为它们能将复杂的、多模态的数据表示为向量嵌入。
用于表示文本和图像数据的知名模型之一是 CLIP。因此,在本教程中,我们使用 CLIP-as-service 作为驱动我们推荐系统的推理引擎。
此外,如果计算不高效,计算向量相似度可能会很慢且成本高昂。我们的应用要求(尊重用户过滤器并提供低延迟推荐)使得在批处理作业中预先计算商品和用户资料之间的相似度变得不切实际。这就是为什么实时计算向量相似度至关重要,可以利用诸如 Hierarchical Navigable Small World (HNSW) 等高效技术。
这些技术在向量数据库中实现。Redis 在 RediSearch 2.4 中提供了向量搜索能力。由于 Redis 是一个内存数据库,推荐商品既快速又是在实时环境中完成的。
特征表示和向量相似性计算已经讨论过,我们仍然需要一个数据结构来弥合多模态数据与向量数据库之间的差距。为此,我们使用 DocArray。可以将 DocArray 视为一个通用的 向量数据库 客户端,支持多模态数据。它提供了 Python 式的接口,只需几行代码即可轻松构建推荐系统。
我们为本应用准备了工具:用于向量相似性搜索的 Redis,用于编码视觉数据的 CLIP-as-service,以及用于表示多模态文档和连接 Redis 的 DocArray。在本教程中,我们将应用这些技术来构建一个基于内容的过滤推荐系统。
步骤如下
在接下来的说明中,我们用于产品推荐的数据来自 Amazon Berkeley Objects 数据集,这是一个包含 Amazon 产品元数据、目录图片和 3D 模型的数据集。
第一步是部署一个 Redis 实例。您可以使用 Docker 创建一个本地 Redis 实例
docker run -d -p 6379:6379 redis/redis-stack:latest
接下来,我们需要安装 DocArray、Jina 以及 clip-client
pip install docarray[redis] jina clip-client
这就是所需的全部设置。现在我们可以开始数据探索了。
Amazon Berkeley Objects 数据集包含产品项目以及图片和元数据(如品牌、国家和颜色)。它代表了一个电子商务网站的库存。
为了本教程的目的,我们可以从 Jina Cloud 下载此数据集的一个子集,该子集已预处理为 DocArray 格式。
首先,使用终端向 Jina Cloud 进行身份验证
jina auth login
接下来,下载数据集
from docarray import DocumentArray, Document
da = DocumentArray.pull('amazon-berkeley-objects-dataset', show_progress=True)
这将返回一个 DocumentArray 对象,其中包含来自 Amazon Berkeley Objects 数据集的样本。我们可以使用 summary() 方法获取概览
da.summary()
╭────────────────────── Documents Summary ──────────────────────╮
│ │
│ Type DocumentArrayInMemory │
│ Length **5809** │
│ Homogenous Documents *True* │
│ Common Attributes **(**'id', 'mime_type', 'uri', 'tags'**)** │
│ Multimodal dataclass *False* │
│ │
╰───────────────────────────────────────────────────────────────╯
╭───────────────────── Attributes Summary ─────────────────────╮
│ │
│ **Attribute** **Data type** **#Unique values** **Has empty value** │
│ ────────────────────────────────────────────────────────── │
│ id **(**'str',**)** **5809** *False* │
│ mime_type **(**'str',**)** **1** *False* │
│ tags **(**'dict',**)** **5809** *False* │
│ uri **(**'str',**)** **4848** *False* │
│ │
╰──────────────────────────────────────────────────────────────╯
或者,我们可以使用 [plot_image_sprites()](<https://docarray.jina.ai/api/docarray.array.document/#docarray.array.document.DocumentArray.plot_image_sprites>) 方法显示前几个商品的图片。
da[:12].plot_image_sprites()
每个产品在 tags 字段中包含元数据信息。
让我们看看 tags 的内容
da[0].tags
{'height': '1926',
'country': 'CA',
'width': '1650',
'product_type': 'ACCESSORY',
'color': 'Blue',
'brand': 'Thirty Five Kent',
'item_name': "Thirty Five Kent Men's Cashmere Zig Zag Scarf, Blue"}
稍后,我们将使用这些元数据根据用户的偏好过滤推荐结果。
为了为我们的数据集创建向量嵌入,我们首先需要一个用于 CLIP-as-service 推理的 token
# Create a Jina token to be used for CLIP-as-service inference
jina auth token create fashion -e 30
然后我们可以开始编码数据。务必将创建的 token 传递给 Client 对象
from clip_client import Client
c = Client(
'grpcs://api.clip.jina.ai:2096', credential={'Authorization': 'your-auth-token'}
)
encoded_da = c.encode(da, show_progress=True)
编码数据集需要几分钟。完成后,我们将继续下一步。
至此,我们的数据已经编码完成,可以进行索引了。
为此,我们创建一个连接到 Redis 服务器的 DocumentArray 实例。指定正确的嵌入维度和过滤列非常重要
# Configure a new DocumentArray with a Redis document store
redis_da = DocumentArray(storage='redis', config={
'n_dim': 768,
'columns': {
'color': 'str',
'country': 'str',
'product_type': 'str',
'width': 'int',
'height': 'int',
'brand': 'str',
}
})
# Index data
redis_da.extend(encoded_da
欲了解更多信息,请参阅 DocArray 中的 Redis 文档存储。
为了理解推荐逻辑,请考虑以下示例:Eleanor 决定给她的衣橱添一条围巾,并在我们的商店里看了几条。她喜欢的颜色是海军蓝,并且预算必须控制在 25 美元以下。
我们的推荐功能应该允许指定这些要求,并根据浏览历史推荐商品,重点关注最近浏览的商品。
因此,我们通过给予最近浏览的商品更多权重来组合它们的嵌入向量
让我们实现一个函数,该函数根据最近浏览商品的嵌入向量的加权平均值来推荐产品,同时考虑用户过滤器。也就是说,在推荐的商品中,我们希望突出显示购物者最近浏览过的商品。
因此,我们通过给予最近浏览的商品更多权重来组合它们的嵌入向量
import numpy as np
def recommend(view_history, color=None, country=None):
embedding = np.average(
[doc.embedding for doc in view_history],
weights=range(len(view_history), 0, -1),
axis=0
)
user_filter = ''
if color:
user_filter += f'@color:{color} '
if country:
user_filter += f'@country:{country} '
return redis_da.find(embedding, filter=user_filter)
当客户查看产品时显示相关的推荐,我们需要三个步骤
我们可以通过以下函数实现这一点
k = 5
view_history = []
def view(item: Document, view_history, color=None, country=None):
print(item.tags['item_name'], ':')
item.display()
view_history.insert(0, item)
view_history = view_history[:k]
recommendations = recommend(view_history, color=color, country=country)
recommendations.plot_image_sprites()
return recommendations
让我们试几次。首先,我们来看看商店里的第一件商品及其推荐
recommended = view(redis_da[0], view_history
这显示了一条引人注目的围巾,标记为“Thirty-Five Kent Men’s Cashmere Zig Zag Scarf, Blue”
……以及配套的推荐
它们是否符合用户的过滤器要求?
让我们检查推荐列表中的第三个商品,并应用过滤器 color=’Navy‘ 以确保更佳匹配
recommended = view(recommended[2], view_history, color='Navy')
……这产生了更好的商品展示和推荐
Thirty-Five Kent 男士羊绒锯齿围巾,蓝色
现在,推荐函数返回与围巾视觉上最相似,同时也满足过滤器 color='Navy' 的商品。
成功!而且,或许还带来了一笔新的电子商务销售。
以上说明简要概述了在线商店产品推荐流程的构建模块。
欢迎您进一步探索。我们创建了一个 GitHub 仓库 ,其中包含使用我们刚刚展示的相同数据集和技术的商品商店界面的源代码。
这个演示刚刚向您展示了向量相似性搜索如何提供低延迟的实时推荐,同时尊重用户偏好和过滤器选择。
但它的速度有多快呢?让我们看看推荐查询的延迟数据。您可以在命令行控制台中找到日志
Retrieving products ... Retrieving products takes 0 seconds (0.01s)
这意味着计算推荐只需要大约 10 毫秒!
当然,还有改进的空间,尤其是在质量方面。例如,我们可以想出更复杂的方法来建模用户的资料和兴趣。我们还可以整合更多类型的数据,例如 3D 模型和视频。这部分留给读者作为练习。
向量相似性搜索是在实时环境中实现推荐的关键技术。
您的下一步
使用 DocArray 作为处理多模态数据和与向量数据库接口的便捷数据结构。查阅 DocArray 文档 开始使用,并联系 Redis AI/ML 团队 获取关于 Redis 向量搜索的更多信息。
开始使用 Redis Cloud 免费套餐。