關凱軒 禹素萍
(東華大學信息科學與技術學院,上海 201620)
隨著互聯網的快速發展,各行各業的信息資訊正在呈爆炸式增長的態勢。在信息過載[1]的時代,如何快速在海量信息中找到自己感興趣的信息成為當務之急,推薦系統在這樣的時代背景下應運而生。
推薦算法經歷了從傳統的協同過濾[2],因子分解機到深度學習算法大行其道的發展過程,尤其是2015 年之后,隨著Wide&Deep[3],FNN[4]等一大批深度推薦模型的提出,深度學習模型成為了推薦系統的主流,推薦效果越來越好。同時,海量數據的處理需求也催生了大數據平臺工具的進化,大數據存儲,傳輸,計算等組件發展日趨成熟。
深度學習模型的表達能力強,與傳統模型相比能夠進行特征間的深度交叉,從而挖掘出特征間更多的潛藏信息,網絡結構也可以隨著業務不同而改變,十分靈活。而Spark,Flink 等大數據計算框架擅長從后端數據庫,日志系統等數據中提取中模型訓練所需的樣本數據,為深度模型提供材料。
本文主要在現有推薦算法的基礎之上,結合大數據處理工具對推薦系統進行設計。通過TensorFlow平臺實現DIN[5]深度學習模型的端到端訓練與部署;通過HDFS,Spark,Kafka 等大數據技術保證海量用戶物品數據,模型數據存儲的穩定,計算的實時高效。二者的結合保證了推薦系統的運行的穩定和推薦的良好效果。
系統采用模塊化結構設計。各模塊之間相互分離,耦合程度低,從而方便后續的維護與拓展。推薦系統整體架構設計如圖1 所示。

圖1 推薦系統整體架構設計
推薦系統由數據存儲,特征處理,模型離線訓練,模型線上服務與網站前后端設計等部分組成。各部分的功能如下:
1.1.1 數據存儲層
主要負責用戶特征,物品特征,用戶Embedding,物品Embedding 等特征數據以及訓練模型數據的存儲。為了解決模型線上服務響應的實時性與海量用戶物品特征存儲的問題,采用分級存儲方式。HDFS 容量近乎無限大[6],但訪問速度慢,適合用來存儲歷次處理的全量數據與模型數據;MySQL 作為關系型數據庫,用于存儲用戶注冊登錄信息,電影相關信息等,用作網站后端數據庫使用;Redis 作為內存型數據庫,訪問速度快,用來載入線上服務所需特征;Elasticsearch 提供全文檢索功能,作為搜索服務器提供電影全文檢索功能。
1.1.2 數據與特征處理
數據處理部分主要負責推薦系統的用戶行為日志處理、數據存儲層數據的聚合更新、推薦模型訓練樣本數據與線上特征的生成等。Spark 離線計算能力強,并且有Spark MLlib 庫,可以用來定時生成模型離線訓練數據和線上特征更新,Flink 作為流處理引擎,可以實時處理用戶行為日志,改變用戶的特征,從而實現用戶的個性化實時推薦效果。
1.1.3 離線模型訓練
離線訓練模塊可以利用TensorFlow 平臺實現深度學習模型,利用Spark MLlib 計算用戶物品Embedding 以及實現協同過濾等傳統模型。Embedding 和傳統模型可以實現物品的快速召回,深度學習模型用來對召回的物品進行精排,生成最終的Top-N 推薦列表。
1.1.4 模型線上服務
線上服務要負責與網站后端,離線模型與數據存儲部分交互。使用TensorFlow Serving[7]可以實現模型的端對端訓練,端對端部署。將離線訓練好的模型載入TensorFlow Server 并部署在Docker 容器中,后端服務器通過Http 請求獲取候選物品的模型推斷結果,通過模型返回的預測評分完成對候選物品的排序,從而完成推薦服務。
1.1.5 網頁前后端設計
采用SSM 后端框架以及JQuery,AJAX 等前端技術實現了推薦系統網站的常見功能。
推薦系統只實現了電影推薦的核心功能,因此設計盡可能簡潔。功能設計如圖2 所示。

圖2 系統功能設計
1.2.1 用戶主題
用戶主題實現用戶的歷史行為展示,如評分記錄,搜索記錄等,與此同時用戶的行為數據會被后端系統實時記錄到日志文件中,并通過Flume,Kafka 傳輸,交給Flink 流處理平臺處理后作為用戶實時推薦的特征數據。
為你推薦列表也展示在用戶主題中,通過召回,排序策略為用戶生成可能感興趣的Top-N 電影。
1.2.2 電影主題
電影主題下主要包括電影的描述信息,電影平均評分等統計信息以及由推薦算法計算得到的Top-N 相似電影列表。
1.2.3 網站首頁
首頁包含了按類別分類電影信息的展示和電影搜索框。電影搜索功能由全文檢索引擎Elasticsearch 實現,同時用戶搜索記錄通過后端埋點記錄后可以作為用戶的行為特征。
出于工程上的考慮,推薦系統中經常把推薦模型分為召回和排序兩個階段。召回階段負責把大規模的候選集快速縮減到幾百量級的規模,為了召回速度快,常采用簡單模型;排序階段負責得到精準的排序結果,因此要盡可能的利用所有特征,并使用復雜模型充分挖掘特征。
為了保證物品的召回速度與召回率的平衡,本文采用基于Embedding 的召回方法,并使用局部敏感哈希[8](Locality Sensitive Hashing,LSH)進行快速Embedding 最近鄰計算;為了實現對多特征的精準排序,排序層使用引入注意力機制的DIN 模型。
Embedding 起源于自然語言處理領域谷歌提出的Word2vec[9]模型,基本思想是基于一組詞序列訓練得到Embedding,用Embedding 間的內積距離表示詞之間的接近程度。Item2vec 是Word2vec 在推薦系統界的推廣,把詞序列換成了用戶的觀看序列,購買序列等,從而可以通過用戶已觀看序列推斷用戶感興趣的物品序列。
假設Item2vec 中一個長度為K 的用戶歷史記錄為w1,w2,…,wk,則Item2vec 的優化目標為:

Item2vec 利用wi向量來預測wj向量,可以轉換為圖3 的神經網絡結構,利用梯度下降訓練參數。輸入向量矩陣WV×N的每一個行向量對應的就是我們要找的Embedding。

圖3 Item2vec 的模型結構
Spark MLlib 庫提供了Item2vec 模型,利用Spark 處理rating表(如表1 所示),按時間戳進行排序后,就可以得到用戶的近似評分序列,從而訓練出電影的Embedding,用戶的Embedding 可以由該用戶觀看過的電影Embedding 加權平均后得到。訓練完成后將Embedding 存入到Redis 內存數據庫中,方便召回時實時獲取。

表1 MovieLens rating 表
在召回時,需要逐一計算物品Embedding 之間的相似度,在面對大規模數據集時十分耗時,為了提高召回效率,可以采用局部敏感哈希的方法。
局部敏感哈希(LSH)基于這樣的思想:原始數據空間中的兩個相鄰數據點通過相同的哈希函數映射后,在新的數據空間中相鄰的概率仍然很大,而不相鄰的數據點相鄰的概率很小。因此,對Embedding 進行哈希映射后,相鄰的Embedding 大概率會被劃分到同一個“桶”中,在召回時只需要在一個桶內,或相鄰幾個桶內的元素中進行搜索即可,大大降低了候選集相似度計算的數量。
Spark MLlib 同樣提供了LSH 分桶模型,利用局部敏感哈希可以極大提高召回速度,實現快速召回。
DIN 模型[5]是阿里媽媽用在展示廣告中的CTR 算法,在傳統深度推薦模型的基礎上引入了注意力機制,利用用戶的歷史行為與目標推薦物品之間的相關性計算注意力得分,從而提供更有針對性的推薦結果。
利用Spark 處理MovieLens 數據集,按照“物品特征”“用戶特征”“場景特征”分類,可以提取出以下特征,見表2。

表2 可用的所有特征
為了使評分數據更好的符合DIN 的CTR 預估模型,我們將用戶評分進行二分類處理,評分大于等于3.5 的標記為1,評分低于3.5 的標記為0。
DIN 模型將注意力機制用在了用戶評分電影序列上,注意力模塊中將用戶評過分的電影與候選電影Embedding 以及通過element wise 差值向量合并起來作為輸入,然后喂給全連接層,最后得出注意力權重。網絡模型如圖4 所示。

圖4 DIN 模型結構
結合前面的召回層、排序層算法以及大數據處理工具,我們可以得到推薦模型的詳細架構設計,如圖5 所示。

圖5 推薦策略整體架構
利用前后端埋點,用戶行為日志經過Flume 采集后一方面落盤到HDFS,另一方面由Kafka 傳輸到Flink 進行實時處理,前面提到用戶Embeddig 是由該用戶觀看過的電影Embedding 加權平均得到的,Flink 在得到用戶最新的評分電影后,就可以實時更新用戶的Embeddig,從而改變用戶的推薦結果。
Spark 從HDFS 上獲取全量數據后進行離線處理,一方面得到訓練樣本數據供模型離線訓練,另一方面將特征存儲到Redis中,方便線上服務時獲取。
在模型線上服務時,利用Embeddig 實現候選集的快速召回,排序時后端服務器利用拼接好的用戶特征,通過請求TensorFlow Serving API 得到推斷的結果,然后根據結果排序,生成最終的推薦列表。
衡量推薦系統推薦效果的方法有離線評估和在線測試兩種。離線評估常用來對算法模型本身進行評估,無需將模型部署到線上環境,是最常用最基本的評估方法;線上測試是在實際生產環境中將被測對象分組,分別部署新舊兩套模型來比較模型的效果差異,通過計算視頻觀看時長,訪問數等商業指標來衡量新模型的效果。
本實驗中離線評估指標有準確率(Accuracy),P-R AUC 和ROC AUC[10]。準確率是指分類正確的樣本占總樣本個數的比例,其公式用混淆矩陣可以表示為:

公式中各項含義如表3 所示。
P-R 是指精確率(Precision)和召回率(Recall)變化的曲線。P-R 曲線的橫軸是召回率,縱軸是精確率。
精確率指的是分類正確的正樣本個數占分類器判定為正樣本個數的比例,公式如下:

ROC(the Receiver Operating Characteristic)曲線全稱為“受試者工作特征曲線”。它的橫坐標是FP,縱坐標是TP。
離線評估使用數據集為Movielens-1m 數據集,其中包括了由6000 名用戶對4000 部電影的100 萬條評分數據,每個用戶至少評分20 部電影。用戶和電影從1 號開始連續編號,數據隨機排序。
采用8 核16 線程聯想電腦進行訓練,內存16G,CPU 為AMD-4800H ,Python 版本為3.7,TensorFlow 版本為2.3.0,不使用GPU 加速。
在構建訓練集與數據集時,為了避免引入未來信息,訓練集包含的用戶評分時間不應該晚于測試集數據。利用Spark 劃分訓練集和測試集時,采用時間切割的方式,將用戶評分按照時間戳排序,前80%作為訓練集,后20%作為測試集。
使用TensorFlow Keras 構建神經網絡,使用Adam 優化器,訓練10 個epochs,每次batch 大小設置為64。
將本文所用的DIN 模型與NeuralCF[11],MLP 模型,Wide&Deep[3],DeepFM[12]等模型進行對比實驗,使用Acc,PR AUC 和ROC AUC 測試[1]模型效果,實驗結果如表4 所示。

表4 模型對比結果
由表4 可知,Netural CF 是傳統協同過濾模型的神經網絡化實現,表現效果最差;而DeepFM由于要進行特征間的深度交叉,在小數據集上表現不好,存在比較嚴重的過擬合問題。
DIN,MLP,Wide&Deep 模型的效果較好,其中DIN 模型的綜合表現最好,這是因為DIN 相比MLP 引入了注意力權重,而MLP 只是將所有特征連接后直接送入全連接層。
除了離線測試模型本身的效果之外,生產環境中還可以用線上AB 測試來評估整個推薦系統的效果。
在實際上線項目中,針對不同的用戶,將其userId 計算哈希后對測試分組進行取余操作,將用戶分布到不同的組中,從而采用不同的推薦模型對用戶進行推薦。通過對比不同模型下網站訪問量,播放時長,視頻播放完成情況等測試上線模型的真實效果。
本文利用Spark 等大數據工具搭建了一套完整的電影推薦系統,基于Embedding 和DIN 深度學習模型實現了電影的離線推薦與實時推薦功能,在離線環境下取得了較好的推薦效果。其中對開源技術框架的選型、推薦系統的每個功能模塊做了詳細介紹,清晰的展示了各模塊之間的協作過程;并介紹了推薦系統推薦效果的評價指標和方法。對于如何設計一個工業化的完整的推薦系統來說具有很好的借鑒意義。
但也存在著諸多不足,本文中用到的推薦算法只是對以往算法在電影推薦領域的一個整合和應用,下一步考慮針對電影數據集對現有算法進行改進。