DeepMatch :用于推荐广告的深度召回匹配算法库
今天介紹一下我們的一個(gè)開源項(xiàng)目DeepMatch,提供了若干主流的深度召回匹配算法的實(shí)現(xiàn),并支持快速導(dǎo)出用戶和物品向量進(jìn)行ANN檢索。非常適合同學(xué)們進(jìn)行快速實(shí)驗(yàn)和學(xué)習(xí),解放算法工程師的雙手!
目前支持的算法下面分別從開發(fā)背景,安裝和使用方法以及貢獻(xiàn)和交流幾個(gè)方面介紹一下這個(gè)項(xiàng)目。文末提供了交流群感興趣的同學(xué)不要錯(cuò)過,歡迎找bug和提意見~
背景
眾所周知,目前主流的推薦廣告算法架構(gòu)體系是一個(gè)召回排序的兩階段流程,召回模塊從海量的候選池中召回多樣的相關(guān)的候選物料,排序模塊根據(jù)用戶偏好和上下文信息給出用戶最可能感興趣的一個(gè)有序列表。
隨著深度學(xué)習(xí)技術(shù)的普及,越來越多的深度學(xué)習(xí)算法被應(yīng)用到了工業(yè)界中。筆者自去年畢業(yè)進(jìn)入企業(yè)后,有幸參與了某新業(yè)務(wù)的推薦系統(tǒng)搭建以及用戶體驗(yàn)和業(yè)務(wù)指標(biāo)的優(yōu)化當(dāng)中,其中在召回部分也進(jìn)行過一些基于向量召回的探索并取得了一些收益。
之前在讀研期間出于個(gè)人興趣開發(fā)過一個(gè)基于深度學(xué)習(xí)的點(diǎn)擊率預(yù)測算法庫DeepCTR(https://github.com/shenweichen/DeepCTR),隨著時(shí)間的迭代得到了一些同學(xué)的支持和認(rèn)可,自己也親身使用到了里面的算法應(yīng)用到了自己的業(yè)務(wù)當(dāng)中并取得了顯著的收益。
相比于排序中各種點(diǎn)擊率預(yù)估模型,自己對(duì)于召回模塊的了解還有很多欠缺,借著這個(gè)機(jī)會(huì),抱著學(xué)習(xí)的心態(tài),和幾位熱心的優(yōu)秀小伙伴一起做了DeepMatch這個(gè)項(xiàng)目,希望它能夠幫助到大家!
下面簡單介紹一下如何安裝和使用
安裝和使用
通過pip安裝
pip install -U deepmatch
文檔
https://deepmatch.readthedocs.io/en/latest/
使用例子
這篇文章是基于v0.1.0寫的,如果以后版本升級(jí)了發(fā)現(xiàn)運(yùn)行不了,可以選擇回退到v0.1.0版本,或者去git倉庫里examples目錄下運(yùn)行最新的代碼。(https://github.com/shenweichen/DeepMatch)
下面以大家比較熟悉的YoutubeDNN為例子,給大家介紹如何使用deepmatch進(jìn)行召回模型的訓(xùn)練,用戶和物品向量的導(dǎo)出,以及使用faiss進(jìn)行近似最近鄰搜索。其他算法的接口和任務(wù)流程基本一樣~
整段代碼不到100行,可以是非常的方便進(jìn)行學(xué)習(xí)和使用了~
完整代碼見鏈接 https://github.com/shenweichen/DeepMatch/blob/master/examples/run_youtubednn_sampledsoftmax.py
import?pandas?as?pd from?deepctr.inputs?import?SparseFeat,?VarLenSparseFeat from?preprocess?import?gen_data_set,?gen_model_input from?sklearn.preprocessing?import?LabelEncoder from?tensorflow.python.keras?import?backend?as?K from?tensorflow.python.keras.models?import?Modelfrom?deepmatch.models?import?* from?deepmatch.utils?import?sampledsoftmaxloss#?以movielens數(shù)據(jù)為例,取200條樣例數(shù)據(jù)進(jìn)行流程演示data?=?pd.read_csvdata?=?pd.read_csv("./movielens_sample.txt") sparse_features?=?["movie_id",?"user_id","gender",?"age",?"occupation",?"zip",?] SEQ_LEN?=?50 negsample?=?0#?1.?首先對(duì)于數(shù)據(jù)中的特征進(jìn)行ID化編碼,然后使用?`gen_date_set`?and?`gen_model_input`來生成帶有用戶歷史行為序列的特征數(shù)據(jù)features?=?['user_id',?'movie_id',?'gender',?'age',?'occupation',?'zip'] feature_max_idx?=?{} for?feature?in?features:lbe?=?LabelEncoder()data[feature]?=?lbe.fit_transform(data[feature])?+?1feature_max_idx[feature]?=?data[feature].max()?+?1user_profile?=?data[["user_id",?"gender",?"age",?"occupation",?"zip"]].drop_duplicates('user_id')item_profile?=?data[["movie_id"]].drop_duplicates('movie_id')user_profile.set_index("user_id",?inplace=True)user_item_list?=?data.groupby("user_id")['movie_id'].apply(list)train_set,?test_set?=?gen_data_set(data,?negsample)train_model_input,?train_label?=?gen_model_input(train_set,?user_profile,?SEQ_LEN) test_model_input,?test_label?=?gen_model_input(test_set,?user_profile,?SEQ_LEN)#?2.?配置一下模型定義需要的特征列,主要是特征名和embedding詞表的大小embedding_dim?=?16user_feature_columns?=?[SparseFeat('user_id',?feature_max_idx['user_id'],?embedding_dim),SparseFeat("gender",?feature_max_idx['gender'],?embedding_dim),SparseFeat("age",?feature_max_idx['age'],?embedding_dim),SparseFeat("occupation",?feature_max_idx['occupation'],?embedding_dim),SparseFeat("zip",?feature_max_idx['zip'],?embedding_dim),VarLenSparseFeat(SparseFeat('hist_movie_id',?feature_max_idx['movie_id'],?embedding_dim,embedding_name="movie_id"),?SEQ_LEN,?'mean',?'hist_len'),]item_feature_columns?=?[SparseFeat('movie_id',?feature_max_idx['movie_id'],?embedding_dim)]# 3. 定義一個(gè)YoutubeDNN模型,分別傳入用戶側(cè)特征列表`user_feature_columns`和物品側(cè)特征列表`item_feature_columns`。然后配置優(yōu)化器和損失函數(shù),開始進(jìn)行訓(xùn)練。K.set_learning_phase(True)model?=?YoutubeDNN(user_feature_columns,?item_feature_columns,?num_sampled=5,?user_dnn_hidden_units=(64,?16)) #?model?=?MIND(user_feature_columns,item_feature_columns,dynamic_k=True,p=1,k_max=2,num_sampled=5,user_dnn_hidden_units=(64,16),init_std=0.001)model.compile(optimizer="adagrad",?loss=sampledsoftmaxloss)??#?"binary_crossentropy")history?=?model.fit(train_model_input,?train_label,??#?train_label,batch_size=256,?epochs=1,?verbose=1,?validation_split=0.0,?)# 4. 訓(xùn)練完整后,由于在實(shí)際使用時(shí),我們需要根據(jù)當(dāng)前的用戶特征實(shí)時(shí)產(chǎn)生用戶側(cè)向量,并對(duì)物品側(cè)向量構(gòu)建索引進(jìn)行近似最近鄰查找。這里由于是離線模擬,所以我們導(dǎo)出所有待測試用戶的表示向量,和所有物品的表示向量。test_user_model_input?=?test_model_input all_item_model_input?=?{"movie_id":?item_profile['movie_id'].values,?"movie_idx":?item_profile['movie_id'].values}#?以下兩行是deepmatch中的通用使用方法,分別獲得用戶向量模型和物品向量模型 user_embedding_model?=?Model(inputs=model.user_input,?outputs=model.user_embedding) item_embedding_model?=?Model(inputs=model.item_input,?outputs=model.item_embedding) #?輸入對(duì)應(yīng)的數(shù)據(jù)拿到對(duì)應(yīng)的向量 user_embs?=?user_embedding_model.predict(test_user_model_input,?batch_size=2?**?12) #?user_embs?=?user_embs[:,?i,?:]??i?in?[0,k_max)?if?MIND item_embs?=?item_embedding_model.predict(all_item_model_input,?batch_size=2?**?12)print(user_embs.shape) print(item_embs.shape)#?5.?[可選的]如果有安裝faiss庫的同學(xué),可以體驗(yàn)以下將上一步導(dǎo)出的物品向量構(gòu)建索引,然后用用戶向量來進(jìn)行ANN查找并評(píng)估效果test_true_label?=?{line[0]:[line[2]]?for?line?in?test_set} import?numpy?as?np import?faiss from?tqdm?import?tqdm from?deepmatch.utils?import?recall_N index?=?faiss.IndexFlatIP(embedding_dim) #?faiss.normalize_L2(item_embs) index.add(item_embs) #?faiss.normalize_L2(user_embs) D,?I?=?index.search(user_embs,?50) s?=?[] hit?=?0 for?i,?uid?in?tqdm(enumerate(test_user_model_input['user_id'])):try:pred?=?[item_profile['movie_id'].values[x]?for?x?in?I[i]]filter_item?=?Nonerecall_score?=?recall_N(test_true_label[uid],?pred,?N=50)s.append(recall_score)if?test_true_label[uid]?in?pred:hit?+=?1except:print(i) print("recall",?np.mean(s)) print("hr",?hit?/?len(test_user_model_input['user_id']))貢獻(xiàn)者
一個(gè)人的力量有限,感謝一起參與開發(fā)的小伙伴們~~他們分別是:
王喆 京東廣告算法工程師
blog: https://zhuanlan.zhihu.com/c_1218845039004119040
github: https://github.com/wangzhegeek
蔡慶亮 字節(jié)跳動(dòng)高級(jí)廣告算法工程師
blog: https://blog.csdn.net/cqlboat
github:https://github.com/LeoCai
楊婕妤,浙江大學(xué)研二找工作????,瘋狂求各大公司收留
mail: yangjieyu@zju.edu.cn
github:https://github.com/Eleanoryuyuyu
最后
這個(gè)項(xiàng)目其實(shí)從立項(xiàng)到第一次發(fā)布拖了比較長的時(shí)間,一方面是大家主要還是工作的同學(xué)居多,可能更多的是利用周末的時(shí)間進(jìn)行開發(fā),響應(yīng)時(shí)間會(huì)比較長。另一方面,我在開始的時(shí)候其實(shí)也不知道要做什么樣子,也是摸著石頭過河,各種接口中途改了很多次,核心還是希望用戶在使用的時(shí)候不會(huì)感到困惑也能夠方便大家的理解。
還是希望大家多多支持,可以給我們來個(gè)star! https://github.com/shenweichen/DeepMatch
【點(diǎn)擊閱讀原文直達(dá)】 另外悄悄透露下:我們還有若干算法已經(jīng)開發(fā)完成,等待測試好了就會(huì)公布!
往期精彩回顧適合初學(xué)者入門人工智能的路線及資料下載機(jī)器學(xué)習(xí)在線手冊(cè)深度學(xué)習(xí)在線手冊(cè)AI基礎(chǔ)下載(pdf更新到25集)本站qq群1003271085,加入微信群請(qǐng)回復(fù)“加群”獲取一折本站知識(shí)星球優(yōu)惠券,請(qǐng)回復(fù)“知識(shí)星球”喜歡文章,點(diǎn)個(gè)在看
總結(jié)
以上是生活随笔為你收集整理的DeepMatch :用于推荐广告的深度召回匹配算法库的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 关于逻辑回归,面试官们都怎么问
- 下一篇: 【零基础入门数据挖掘】-模型融合