在DocArray中使用Redis后端,基于向量相似性搜索可以快速搭建一个实时商品推荐系统。现在,跟上我们的脚步,一起了解搭建系统的关键步骤,并且深入了解推荐的原理吧!
推荐系统会根据用户画像、历史行为(如购买、喜欢、浏览等),给用户的兴趣建模,主动提供个性化推荐。它可以提升转化率并保持用户忠诚度,因而被广泛应用在各类电子商务网站。
图片来自:https://www.mdpi.com/2076-3417/10/16/5510/htm
过去,构建并部署推荐系统通常是一个非常复杂的任务。但现在,通过在 DocArray 中使用 Redis 后端,使用最新的向量相似度搜索技术,可以快速构建实时商品推荐系统。
为电子商务网站构建推荐系统涉及很多挑战,以下列出了一些要考虑的问题:
随着技术的不断发展,用户需求的不断增长,构建推荐系统的方法也应该不断提升。
在本文中,我们将向您展示如何使用最新的向量搜索技术构建实时商品推荐系统,并使用自定义过滤器来提供个性化推荐。我们使用的工具包括 Redis 和 DocArray。
from docarray import DocumentArray
redis_da = DocumentArray(storage='redis')
在 DocArray 中使用 Redis 后端非常简单方便,更多信息可以查阅文档。
https://docarray.jina.ai/advanced/document-store/redis/
如何构建推荐系统?
在构建推荐系统时,有一些常见的方法:
本文重点是改进基于内容的过滤算法。如果您对此算法不熟悉,可以阅读一下谷歌的基于内容的过滤算法概述。
https://developers.google.com/machine-learning/recommendation/content-based/basics
在实现基于内容的过滤算法时,需要考虑两个因素。
首先,在为用户和商品建立特征向量时,充分利用所有模态数据是非常重要的。仅仅依靠关键词或者一组特征可能无法有效地代表复杂的数据。因此,使用前沿的 AI 模型是很有必要的,它们可以将复杂的多模态数据表示为嵌入向量 embedding。
CLIP 是一个可以同时表示文本和图像的神经网络模型,因此我们可以使用<a href="http://http://mp.weixin.qq.com/s?__biz=MzkyODIxMjczMA==&mid=2247494451&idx=3&sn=def4556c7f945b0052fbd2793614dd3a&chksm=c21e98a6f56911b0d24680fda11674b616f2750aa4914f60c4fc2e713d11a37ae788e4501216&scene=21#wechat_redirect"> CLIP-as-service 作为推理引擎来支持我们的推荐系统。
其次,如果不能高效地计算向量相似度,计算过程可能会非常慢并且成本高昂。而且在批处理中提前计算用户和 item
间的向量相似度并不现实,因为我们的应用程序需要遵守用户过滤器,并提供低延迟推荐。所以在这个实时商品推荐系统里,我们需要使用高效算法,例如 Hierarchical Navigable Small World(HNSW) 来实时计算相似度。
这些技术都集成在向量数据库中,RediSearch 2.4 中提供向量搜索功能。因为 Redis 是一个内存数据库,所以推荐可以保证实时进行。
由于推荐系统包含 特征表示 和 向量相似度计算,所以我们需要一种数据结构跨越多模态数据和向量数据库之间的鸿沟。DocArray 就是不二之选,DocArray 提供了便捷的多模态数据处理功能,具备基于 Protobuf 提供高性能的网络传输性能,同时也为多种向量存储方案提供统一的 API 接口。
也就是说 DocArray 既支持多模态数据的处理、传输、存储,又可以作为通用向量数据库的客户端。在这个推荐系统中,DocArray 既可以用来表示用户和物品的信息,又可以对它们进行特征表示。更重要的,只需几行代码就可以轻松构建推荐系统。
DocArray 可以处理多模态数据,例如图像、视频、音频和 3D 网格,并且它可以将数据存储到不同的向量数据库中,如 Redis、ElasticSearch、 Weaviate、 Qdrant。
DocArray + Redis 的解决方案
我们已经为应用组装了 Redis、CLIP-as-service 和 DocArray,其中 Redis 用于向量相似性搜索,CLIP-as-service 用于编码文本和图片,DocArray 用来表示多模态 document 并存储到Redis。我们将应用这些技术来搭建一个基于内容过滤的推荐系统。
具体过程如下:
安装 DocArray 和 Redis
首先需要配置 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 Dataset,这个数据集包含带有图片和元数据(例如品牌、国家和颜色)的商品项。
首先,使用终端向 Jina AI Cloud 发送身份验证:
jina auth login
接着,下载数据集:
from docarray import DocumentArray, Document
da = DocumentArray.pull('amazon-berkeley-objects-dataset', show_progress=True)
这会返回一个包含 Amazon Berkeley Objects 数据集样本的 DocumentArray 对象。使用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()
方法来显示第一批商品的图像。
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"}
稍后,我们会使用元数据和用户的喜好过滤推荐结果。
创建 embedding
为了给我们的数据集创建embedding,我们需要用于 CLIP-as-service 的 token
jina auth token create fashion -e 30
然后就可以编码我们的数据了,一定要将创建的 token 发送给客户端对象:
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
此时,我们的数据已经完成编码并准备索引。
为此,我们创建了一个连接 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 DocumentStore:
https://docarray.jina.ai/advanced/document-store/redis/
获取推荐结果
为了更好地理解推荐系统的运行逻辑,举个例子:小美想要购买一条围巾,并且逛了我们的商店。她最喜欢海军蓝色,预算在 100 元以下。我们的系统在推荐时应该综合考虑用户的要求和基于浏览历史的推荐item
,尤其是最近查看的 item
。因此,可以通过给最近浏览的 item
赋予更高的权重来组合 embedding。
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(品牌名)男士山羊绒 Zig Zag 围巾,蓝色”:
飞起来的推荐速度
本项目的数据集和源代码都已经开源,GitHub 地址:https://github.com/jina-ai/product-recommendation-redis-docarray
这个演示只是展示了向量相似性搜索是如何在实时推荐系统中满足用户的偏好以及过滤器的筛选的,但是它究竟快到什么程度呢?你可以在控制台中找到运行日志,日志中包含了推荐查询的延迟。
Retrieving products ... Retrieving products takes 0 seconds (0.01s)
这意味着推荐的计算仅仅只需要 10 毫秒左右。
当然对于推荐系统来说,无论是速度还是推荐的质量方面都有提升的空间,例如,我们可以用更复杂的算法建模用户画像和用户偏好。此外,我们还可以使用更复杂的数据,如 3D 模型和视频等等。这些就留给你们慢慢探索了。
下一步的探索!
向量相似性搜索是基于上下文语义的实时搜索技术,你可以继续探索:
更多资料
GitHub: http://github.com/docarray/docarray
文档:docarray.jina.ai
原文链接:https://jina.ai/news/real-time-product-recommendation-using-redis-and-docarray/
本项目地址:https://github.com/jina-ai/prod