電影推薦系統(tǒng) demo 界面
推薦系統(tǒng)[1](Recommender System,RS)能夠根據(jù)用戶的偏好主動(dòng)為用戶推薦商品或項(xiàng)目。它通過用戶的歷史數(shù)據(jù)來發(fā)掘用戶興趣偏好,從而將用戶可能感興趣的物品推送給用戶,一個(gè)設(shè)計(jì)出色的推薦系統(tǒng)能夠?yàn)槠髽I(yè)帶來可觀的經(jīng)濟(jì)效益。一個(gè)完整的推薦系統(tǒng)的組成必須包括三個(gè)要素:用戶模型、推薦對(duì)象模型、推薦算法。其中推薦算法是推薦系統(tǒng)的核心。目前,較成熟的推薦算法主要有:基于協(xié)同過濾的推薦、隱含語義模型、基于圖模型的推薦、組合推薦等。本文將為大家介紹如何利用 Milvus 搭建基于圖的推薦系統(tǒng)。
| 主要技術(shù)
基于圖的卷積神經(jīng)網(wǎng)絡(luò)
- PinSage
PinSage[2]是由斯坦福和 Pinterest 公司合作提出了第一個(gè)工業(yè)級(jí)別(數(shù)十億節(jié)點(diǎn)和數(shù)百億邊)基于 GCN(Graph Convolutional Neural,圖神經(jīng)網(wǎng)絡(luò)) 的推薦系算法。用戶在 Pinterest 網(wǎng)站中將自己感興趣的內(nèi)容(pins)與相關(guān)的板塊(broads)進(jìn)行標(biāo)記,其中包含了 20 億 pins,10 億 boards 以及 180 億邊(若 pin 在 broads 中,那么它們之間存在一條邊),由此構(gòu)成的二分圖如下圖所示:
該算法的目標(biāo)是利用 pins-broards 二分圖結(jié)構(gòu),生成 pins 的高質(zhì)量 embeddings 用于推薦任務(wù),如相關(guān) pins 推薦。PinSage 的關(guān)鍵創(chuàng)新點(diǎn)主要有[3]:
- 動(dòng)態(tài)卷積:傳統(tǒng)的 GCN 算法對(duì)特征矩陣與全圖進(jìn)行卷積;PinSage 算法對(duì)節(jié)點(diǎn)周圍的鄰域進(jìn)行采樣,通過動(dòng)態(tài)構(gòu)建計(jì)算圖來執(zhí)行高效的局部卷積。
- 采樣構(gòu)造卷積:對(duì)節(jié)點(diǎn)的全部鄰域上執(zhí)行卷積會(huì)導(dǎo)致龐大的計(jì)算圖,因此需要借助采樣減小計(jì)算量。傳統(tǒng)的 GCN 算法檢查 K-hop 圖鄰域;而 PinSage 通過模擬隨機(jī)游走將訪問量最高的設(shè)為重要鄰域,并基于此構(gòu)造卷積。
- 高效 MapReduce:對(duì)于局部卷積的節(jié)點(diǎn)通常有重復(fù)計(jì)算的問題,這是由于節(jié)點(diǎn)的 K-hop 鄰域之間的重疊引起的。PinSage 對(duì)每個(gè)聚合步驟,將所有節(jié)點(diǎn)做映射而無需重復(fù)的計(jì)算,然后將其連接并發(fā)送至相應(yīng)上層節(jié)點(diǎn),最后進(jìn)行歸約以獲取上層節(jié)點(diǎn)的 embeddings。
- DGL
Deep Graph Library(DGL)[4]是一個(gè) Python 軟件包,用于在現(xiàn)有深度學(xué)習(xí)框架(例如 PyTorch,MXNet,TensorFlow 等)之上輕松搭建圖神經(jīng)網(wǎng)絡(luò)模型。它提供了后端適配接口,可輕松移植到其他基于張量、支持自動(dòng)生成的框架。本文的 PinSage 算法就是基于 DGL 和 Pytorch 對(duì)部分算法做了改進(jìn)。詳見https://github.com/dmlc/dgl/tree/master/examples/pytorch/pinsage
Milvus 向量相似度搜索引擎
前面介紹了基于 DGL 運(yùn)用 PinSage 模型可以輕松獲取高質(zhì)量的 embeddings,那么接下來就需要對(duì) embeddings 做相似度搜索,從而找出用戶可能感興趣的項(xiàng)目推薦給用戶。Milvus[5]是一款開源向量相似度搜索引擎,支持使用多種 AI 模型將非結(jié)構(gòu)化數(shù)據(jù)向量化,并為向量數(shù)據(jù)提供搜索分析服務(wù),可廣泛應(yīng)用于圖像處理、機(jī)器視覺、自然語言處理、語音識(shí)別、推薦系統(tǒng)以及新藥發(fā)現(xiàn)。具體實(shí)現(xiàn)方式是:
- 通過深度學(xué)習(xí)模型將非結(jié)構(gòu)化數(shù)據(jù)轉(zhuǎn)化為特征向量,并導(dǎo)入 Milvus 庫。
- 對(duì)特征向量進(jìn)行存儲(chǔ)并建立索引。
- 接收到用戶的向量搜索請(qǐng)求后,返回與輸入向量相似的結(jié)果。
| 系統(tǒng)搭建
系統(tǒng)介紹
接下來將介紹如何利用 Milvus 搭建基于圖的推薦系統(tǒng),如下圖所示,系統(tǒng)主要包含數(shù)據(jù)預(yù)處理、PinSage 模型、數(shù)據(jù)加載、查詢和系統(tǒng)推薦:
1. 數(shù)據(jù)預(yù)處理
本文搭建的推薦系統(tǒng)使用開放的 MovieLens[5]百萬數(shù)據(jù)集(ml-1m),包含 6,000 位用戶對(duì) 4,000 部電影的 1,000,000 條評(píng)價(jià),由 GroupLens Research 實(shí)驗(yàn)室搜集整理。原始數(shù)據(jù)中包含電影的數(shù)據(jù)信息,用戶特征信息,以及用戶對(duì)電影的評(píng)分。本文利用 MovieLens 數(shù)據(jù)集中用戶看過的電影記錄來構(gòu)建一個(gè)具有分類特征的結(jié)構(gòu)圖: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()
2. PinSage 模型處理
利用 PinSage 模型獲取 pins 的 embeddings,本文主要是獲取電影數(shù)據(jù)的特征向量。首先根據(jù)構(gòu)建的二分圖 g 和自定義的電影特征向量維度(默認(rèn) 256 維)生成 PinSage 模型,再利用 PyTorch 訓(xùn)練該模型,然后通過訓(xùn)練好的模型生成 4000 條電影數(shù)據(jù)的特征向量 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)
3. 數(shù)據(jù)加載
將 PinSage 模型生成的電影特征向量 h_item 導(dǎo)入 Milvus 并返回對(duì)應(yīng)的 ID;將電影的 ID 和對(duì)應(yīng)的電影數(shù)據(jù)信息導(dǎo)入 MySQL 結(jié)構(gòu)化數(shù)據(jù)庫。
# Load data to Milvus and MySQL
status, ids = milvus.insert(milvus_table, h_item)
load_movies_to_mysql(milvus_table, ids_info)
4. 查詢
根據(jù)用戶偏好的電影 ID 在 Milvus 中獲取對(duì)應(yīng)的特征向量( embeddings ),然后利用返回的特征向量在 Milvus 中進(jìn)行相似度檢索,根據(jù)返回的相似結(jié)果 ID 在 MySQL 數(shù)據(jù)庫中查找對(duì)應(yīng)的電影信息。
# 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()
5. 系統(tǒng)推薦
最終,根據(jù)查詢的結(jié)果為用戶提供相似電影的推薦。綜上就是推薦系統(tǒng)的主要流程,具體搭建步驟參考 Milvus-Bootcamp:https://github.com/milvus-io/bootcamp/tree/0.10.0/solutions/graph_based_recommend
| 系統(tǒng)展示
該項(xiàng)目也提供了 FastAPI 接口和前端展示,通過模擬用戶登錄電影視頻 APP 并勾選自己喜歡的電影,從而推薦用戶可能感興趣的電影。
| 總結(jié)
基于圖的卷積神經(jīng)網(wǎng)絡(luò) PinSage 通過 pins-broards 二分圖結(jié)構(gòu)生成 pins 的高質(zhì)量 embeddings 用于推薦任務(wù)。而本文利用 MovieLens 數(shù)據(jù)集構(gòu)建 users-movies 二分圖,再利用 DGL 開源包結(jié)合 PinSage 模型生成電影的特征向量,再將此特征向量加載至 Milvus 特征向量相似度搜索引擎,之后根據(jù)用戶偏好在 Milvus 中檢索,得出相似的特征向量以實(shí)現(xiàn)向用戶推薦電影的功能。
本文使用的 Milvus 特征向量相似度搜索引擎可以對(duì)接各種深度學(xué)習(xí)平臺(tái),并運(yùn)用于眾多 AI 領(lǐng)域。Milvus 充分利用現(xiàn)代處理器的并行計(jì)算能力,可以在單臺(tái)通用服務(wù)器上完成對(duì)十億級(jí)數(shù)據(jù)的毫秒級(jí)搜索,助力用戶高效完成非結(jié)構(gòu)化數(shù)據(jù)檢索。
參考資料
- https://patentimages.storage.googleapis.com/0e/96/31/98058cb476cd77/CN105913296A.pdf
- Graph Convolutional Neural Networks for Web-Scale Recommender Systems, arxiv: 1806.01973
- https://medium.com/pinterest-engineering/pinsage-a-new-graph-convolutional-neural-network-for-web-scale-recommender-systems-88795a107f48
- https://docs.dgl.ai/en/latest/
- http://files.grouplens.org/datasets/movielens/ml-1m.zip