电影推荐系统 demo 界面
推荐系统[1](Recommender System,RS)能够根据用户的偏好主动为用户推荐商品或项目。它通过用户的历史数据来发掘用户兴趣偏好,从而将用户可能感兴趣的物品推送给用户,一个设计出色的推荐系统能够为企业带来可观的经济效益。一个完整的推荐系统的组成必须包括三个要素:用户模型、推荐对象模型、推荐算法。其中推荐算法是推荐系统的核心。目前,较成熟的推荐算法主要有:基于协同过滤的推荐、隐含语义模型、基于图模型的推荐、组合推荐等。本文将为大家介绍如何利用 Milvus 搭建基于图的推荐系统。
基于图的卷积神经网络
PinSage[2]是由斯坦福和 Pinterest 公司合作提出了第一个工业级别(数十亿节点和数百亿边)基于 GCN(Graph Convolutional Neural,图神经网络) 的推荐系算法。用户在 Pinterest 网站中将自己感兴趣的内容(pins)与相关的板块(broads)进行标记,其中包含了 20 亿 pins,10 亿 boards 以及 180 亿边(若 pin 在 broads 中,那么它们之间存在一条边),由此构成的二分图如下图所示:
该算法的目标是利用 pins-broards 二分图结构,生成 pins 的高质量 embeddings 用于推荐任务,如相关 pins 推荐。PinSage 的关键创新点主要有[3]:
Deep Graph Library(DGL)[4]是一个 Python 软件包,用于在现有深度学习框架(例如 PyTorch,MXNet,TensorFlow 等)之上轻松搭建图神经网络模型。它提供了后端适配接口,可轻松移植到其他基于张量、支持自动生成的框架。本文的 PinSage 算法就是基于 DGL 和 Pytorch 对部分算法做了改进。详见https://github.com/dmlc/dgl/tree/master/examples/pytorch/pinsage
Milvus 向量相似度搜索引擎
前面介绍了基于 DGL 运用 PinSage 模型可以轻松获取高质量的 embeddings,那么接下来就需要对 embeddings 做相似度搜索,从而找出用户可能感兴趣的项目推荐给用户。Milvus[5]是一款开源向量相似度搜索引擎,支持使用多种 AI 模型将非结构化数据向量化,并为向量数据提供搜索分析服务,可广泛应用于图像处理、机器视觉、自然语言处理、语音识别、推荐系统以及新药发现。具体实现方式是:
系统介绍
接下来将介绍如何利用 Milvus 搭建基于图的推荐系统,如下图所示,系统主要包含数据预处理、PinSage 模型、数据加载、查询和系统推荐:
本文搭建的推荐系统使用开放的 MovieLens[5]百万数据集(ml-1m),包含 6,000 位用户对 4,000 部电影的 1,000,000 条评价,由 GroupLens Research 实验室搜集整理。原始数据中包含电影的数据信息,用户特征信息,以及用户对电影的评分。本文利用 MovieLens 数据集中用户看过的电影记录来构建一个具有分类特征的结构图:users-movies 二分图 g。
# Build graph
graph_builder = PandasGraphBuilder()
graph_builder.add_entities(users, 'user_id', 'user')
graph_builder.add_entities(movies_categorical, 'movie_id', 'movie')
graph_builder.add_binary_relations(ratings, 'user_id', 'movie_id', 'watched')
graph_builder.add_binary_relations(ratings, 'movie_id', 'user_id', 'watched-by')
g = graph_builder.build()
利用 PinSage 模型获取 pins 的 embeddings,本文主要是获取电影数据的特征向量。首先根据构建的二分图 g 和自定义的电影特征向量维度(默认 256 维)生成 PinSage 模型,再利用 PyTorch 训练该模型,然后通过训练好的模型生成 4000 条电影数据的特征向量 h_item。
# Define the model
model = PinSAGEModel(g, item_ntype, textset, args.hidden_dims, args.num_layers).to(device)
opt = torch.optim.Adam(model.parameters(), lr=args.lr)
# Get the item embeddings
for blocks in dataloader_test:
for i in range(len(blocks)):
blocks[i] = blocks[i].to(device)
h_item_batches.Append(model.get_repr(blocks))
h_item = torch.cat(h_item_batches, 0)
将 PinSage 模型生成的电影特征向量 h_item 导入 Milvus 并返回对应的 ID;将电影的 ID 和对应的电影数据信息导入 MySQL 结构化数据库。
# Load data to Milvus and MySQL
status, ids = milvus.insert(milvus_table, h_item)
load_movies_to_mysql(milvus_table, ids_info)
根据用户偏好的电影 ID 在 Milvus 中获取对应的特征向量( embeddings ),然后利用返回的特征向量在 Milvus 中进行相似度检索,根据返回的相似结果 ID 在 MySQL 数据库中查找对应的电影信息。
# Get embeddings that users like
_, user_like_vectors = milvus.get_entity_by_id(milvus_table, ids)# Get the information with similar movies_, ids = milvus.search(param = {milvus_table, user_like_vectors, top_k})sql = "select * from " + movies_table + " where milvus_id=" + ids + ";"
results = cursor.execute(sql).fetchall()
最终,根据查询的结果为用户提供相似电影的推荐。综上就是推荐系统的主要流程,具体搭建步骤参考 Milvus-Bootcamp:https://github.com/milvus-io/bootcamp/tree/0.10.0/solutions/graph_based_recommend
该项目也提供了 FastAPI 接口和前端展示,通过模拟用户登录电影视频 APP 并勾选自己喜欢的电影,从而推荐用户可能感兴趣的电影。
基于图的卷积神经网络 PinSage 通过 pins-broards 二分图结构生成 pins 的高质量 embeddings 用于推荐任务。而本文利用 MovieLens 数据集构建 users-movies 二分图,再利用 DGL 开源包结合 PinSage 模型生成电影的特征向量,再将此特征向量加载至 Milvus 特征向量相似度搜索引擎,之后根据用户偏好在 Milvus 中检索,得出相似的特征向量以实现向用户推荐电影的功能。
本文使用的 Milvus 特征向量相似度搜索引擎可以对接各种深度学习平台,并运用于众多 AI 领域。Milvus 充分利用现代处理器的并行计算能力,可以在单台通用服务器上完成对十亿级数据的毫秒级搜索,助力用户高效完成非结构化数据检索。
参考资料