【日本雅虎新聞推薦】:Embedding-based News Recommendation for Millions of Users(附開源代碼)

本篇論文由日本雅虎團隊發表於KDD 2017,利用深度學習方法將用戶和文章進行embedding化,再進行推薦。

下載地址:http://dacemirror.sci-hub.tw/proceedings-article/b79bf692bc190d28d255671a64aedf02/okura2017.pdf#view=FitH

代碼:https://github.com/Leavingseason/rnn_recsys

有個標準日本英語的介紹視頻:https://www.kdd.org/kdd2017/papers/view/embedding-based-news-recommendation-for-millions-of-users

摘要

    對於新聞推薦來說最重要的就是要把文章的內容和用戶的喜好表達清楚,以及它們之間的關係。協同過濾和低秩分解方法等基於ID的算法並不是很適用於新聞推薦,因爲這類算法很難做到實時更新。常用於信息檢索中的word-based方法雖然在性能上較好,但是它們在處理同義和字的變體以及根據用戶自身的歷史行爲定義每個用戶的個性化query都存在一定的侷限。所以本文提出了一個三層的基於embedding的分佈式表示方法。1利用一個特殊的自編碼器去爲文章編碼。2將歷史信息輸入RNN爲用戶進行編碼 3.直接將編碼的文章和用戶按向量進行內積,爲用戶找到最合適的topN文章。
該方法已經利用日本雅虎首頁推薦的數據進行離線評估,獲得較好的效果。並在線上進行測試,相比於傳統的方法,點擊率提升了23%,用戶停留時間延長了10%

介紹

    新聞類文章具有很強的時效性,所以利用傳統的基於ID的方法,比如協同過濾等非實時的更新就不太合理。而新聞類的推薦需要解決的問題有三個:

1.理解文章的內容

2.理解用戶的愛好

3.基於文章的內容和用戶的喜好爲每個用戶選出他最喜歡的topN文章列表。

對於以上三個問題,作者給出了一個最基本的baseline方法。

就是把一篇文章看作是一系列詞的集合;一個用戶看作是該用戶瀏覽過的所有文章中的詞的集合;

而最簡單的度量文章和用戶的相關度的方法就是看文章中的詞和組成用戶的詞的同現數。這樣的話把所有的詞建立其倒排索引,根據詞的共現就可以很快的爲用戶找到匹配的文章。

這個方法存在的問題有幾點:

1.不能區分同義詞。比如“川普”和“特朗普”其實表達的就是同一個人,但是基於詞的方法就無法對其進行區分,這就會導致在詞頻統計的時候,把明明是同一個意思的詞分到不同的桶裏,照成統計的誤差。

2.用戶的瀏覽歷史其實是個時序相關的多個sessions,而不是簡單的詞的集合。新聞類的推薦更多的是在用戶的及時興趣上,如果過了這個興趣的窗口期,就過了推薦的最佳時間。而剔除了時序的詞集合完全不能考慮到這個特徵;並且用戶不同的瀏覽量都會照成不同長度的瀏覽歷史,如何有效的對不同長度的瀏覽歷史進行統一也是一個問題。

所以考慮到這些,作者提出了一個基於embedding的推薦策略,該策略分三步:

1.基於一種弱監督的降噪自編碼器來對文章進行embedding向量化;

2.利用用戶的歷史瀏覽信息作爲rnn的訓練數據生成用戶的embedding向量;

3.直接利用文章embedding向量和用戶的embedding向量做內積,匹配出用戶最可能感興趣的topN文章列表,並對該列表做去重。

該方法的關鍵在於只需要使用內積來計算文章和用戶的相關性,這樣的話就可以把該算法工業化落地,因爲內積的速度是可以滿足真實場景下的實時推薦的。而推薦系統只需要提前計算好文章和用戶的embedding向量。該方法可以說同時在效率和效果上都能滿足工業化需求。

整體推薦流程

日本雅虎團隊將該推薦策略應用在來日本雅虎的智能手機主頁推薦業務上。整個流程分爲五部分:

1.識別

 獲得預先根據用戶歷史數據計算好的用戶特徵

2.匹配

使用用戶特徵從所有可用的文章中提取出候選文章集

3.排序

按照一定的排序規則算法對文章進行排序

4.去重

移除包含相同信息的文章

5.廣告

做業務還是要掙錢的。

    而以上這一系列動作都需要在用戶的請求和顯示推薦的文章這之間的幾百毫秒內全部完成,但是每天能推薦的文章是一直在變的,有成千上萬的文章被刪除,也有成千上萬的文章加進來,所以必須得提前將所有的文章emebdding和用戶embedding計算好。然後再針對每個用戶去選取候選的文章,選取的方式就是計算用戶embedding和文章embedding的內積,根據內積的大小設置預測來選取一定數量的候選文章集。

    有了候選文章集就可以繼續利用其他的因素,來對文章進一步的精排序,比如文章的訪問量,文章的新鮮度等等,這就需要進一步對文章,用戶以及文章用戶之間的上下文信息進行特徵工程。

    這裏需要處理的另外一個問題就是提取出的文章肯定會存在相似文章的情況,比如現在有兩片文章分別問“特朗普大選”和“川普大選”其實是一樣的文章,但是如果用前面提到的基於詞的算法就無法對這兩篇文章進行區分,但是基於embedding的話就可以對這兩篇文章進行區分了。本文作者採用的是利用貪心策略對推薦出的文章集合進行去重。分別計算推薦出的文章embedding的餘弦相似度,當排序後更加靠前的文章和後面的文章餘弦相似度超過一定閾值後,就把後面的文章認爲和前面的文章重複,把後面出現的文章從推薦列表中去掉。這一步對於大數據量的新聞推薦來說是很重要的,因爲推薦的文章數據量一大,就會存在很大重複的文章,如果不對重複文章進行去重,那麼一旦推薦列表裏存在推薦概率較高的文章有很多是重複文章的情況,就會給用戶推薦大量的重複文章,降低用戶的滿意度和體驗度,因爲用戶看到了大量的一樣的文章。還降低了文章的多樣性,不能進一步探索用戶的興趣,無法很好的粘住用戶。

    最後是廣告這塊,這塊就不說了,工作就是爲了掙錢,畢竟廣告是流量變現最快最好的方式。

文章embedding的生成方法

作者利用降噪自編碼器來生成embedding向量,但是自編碼器只能將原始的輸入進行編碼,無法學習輸入的文章是否是相同或者不同的文章,所以需要對降噪自編碼器的損失函數做來一點修改,加入一點監督信息,讓模型能學習到文章之間的差異和相似。

原始的降噪自編碼器是這樣的:

                                

原始輸入x,經過損壞函數q(x),破壞原始的輸入x,生成了被損壞的\widetilde{x},然後進過全連接f(x)就可以隱層的表示h了,再通過同樣的方式把h重建回原來的x;就是上圖中的y。最終的損失函數就是要讓重建的y和真實的輸出x儘量一致。做q(x)的目的就是爲了讓學習出來的f(x)能更加的魯棒。

作者對損失函數做了優化:

和原始的降噪自編碼器對一一下就能發現,改動主要在損失函數,但是這裏整體的網絡結構是個三元組,(x_0,x_1,x_2)。其中x_0x_1來自同一類目,x_0x_2來自不同的類目。可以看出來主要的區別就是在損失函數中加入了對三個輸出的隱層的度量,使得h_0h_1的相似度能大於h_0h_2的相似度。從L_T這部分損失就可以看出來,log(1+exp(x))要想最小化就需要exp(x)儘量等於0,那麼x就要趨近於負無窮。這裏的x就是h_0^Th_2-h_0^Th_1,要讓h_0^Th_2-h_0^Th_1趨近於負無窮就是要讓h_0^Th_1遠大於h_0^Th_2

最後模型生成的h就是輸入x的emebdding向量。

用戶embedding向量的生成方法

 先從前面提到過的基於詞的模型講其,再循環漸進。
第一個是基於詞的模型:
    就是把一篇文章看作詞的集合;
    一個用戶看作他瀏覽的文章的詞的集合;
    用戶和文章的相關性就利用詞的共現的線性函數表示;
文章a就是類似詞袋模型一樣是個稀疏向量,假設全部詞彙的數量是v,文章表示向量a的維度就是就是v,但是和詞袋模型不一樣的是,這裏有出現的是1,沒有出現時0。沒有數量的統計。
用戶的一樣,維度也是v,瀏覽的文章所有出現詞,出現的詞位置爲1,沒有出現的爲0,向量的值只有0或者1。

相似度度量如下:

                                       

這裏u_t就是當前t時刻的用戶向量,a就是文章的向量,兩者的維度都是詞彙的總數v,那麼上面的相似度度量R(),其實就是直接內積,只有兩者都爲1纔能有值,否則就是0。就用該方法來計算相似度。

很明顯這裏的問題是:

1. 不管用戶向量或者文章向量都很稀疏,必須兩者有相同的詞纔會認爲相關,但是如果一篇文章包含了相似詞但是不是相同詞就會被認爲不相關,這很明顯是不合理的,會影響文章召回的精度。

2. 還有一點是把文章和用戶瀏覽歷史都看成來集合,沒有考慮到用戶瀏覽的時間順序,顯然用戶對最近瀏覽的文章最感興趣,而且詞彙出現的次數也能反應用戶對不同詞彙的喜好程度。所以作者們後提出來一個衰減模型。

衰減模型

主要是對上面的基於詞的模型做了兩點優化。

1.就是把文章的表示不在使用詞來表示,而是用基於自編碼器的embedding來表示,這個方法就能解決相似詞不能識別的問題;

2.就是爲了考慮時序信息,對用戶的瀏覽歷史做了加權,加大來近期的權重,減少來較長時間前瀏覽的權重。

用戶的表示向量可以被表示爲

                                                   

看着花裏胡哨的,這裏的\alpha是需要學習出來的和文章a同樣維度的向量,中間那個同心圓就是基於元素位的點乘,後面的\beta是衰減係數,如果\beta爲0其實就是正常的對向量的平均。

循環模型

雖然使用了衰減模型,但是模型衰減的程度是依靠超參數設置的指數衰減決定的,而且時序的相關性也不能很好的體現。所以最後作者們用上了RNN,利用RNN來按時序計算用戶的embedding,而RNN的輸入就是用戶瀏覽文章的序列,文章以其自編碼器生產的embedding向量作爲輸入。作者分別嘗試來原始的RNN,LSTM,GRU三種RNN結構。原始RNN和LSTM都在一定程度上存在梯度爆炸和消失問題,只有基於GRU的RNN沒有類似情況發生。

最後是實現結果,不用說,肯定提升比較明顯,不然也不發論文了。   

                                     

這裏有一點:該模型上線其實相對比較困難,不能頻繁更新模型,原因如下

 1.模型訓練時間長,當前部署的模型在 GPU 上得訓練一週時間;

 2. 一旦更新了計算文章embedding的DAE,那麼就需要對這些文章的索引全部重新更新;

 3. 一旦文章的embedding變了,那麼用戶的embedding也得跟着變;

 4. 保存用戶embedding的數據存儲和保存文章embedding的搜索索引必須同步更新。

所以線上使用了兩個分開的模型,方便模型的切換,並且經過數據分析,三個月後系統的性能下降到和基線一致,所以每三個月更新一次最佳。

總結

這算是把深度學習技術應用到實際線上的一次嘗試把,感覺它使用自編碼器這步操作還是挺6的,利用瀏覽歷史來生產用戶embedding是一個 很直觀的方式,但是文章也說了,上線是比較麻煩的,感覺是不是會有更好的計算用戶embedding的方式,比如用上tranformer來做,可不可能實際應用起來會方便點,這個也不敢確定。

還有一點就是給我的感覺這裏的推薦其實就是基於序列的點擊率預估,可以結合這篇paper《Session-based Recommendations with Recurrent Neural Networks 》看一下,或者直接看我的博客https://blog.csdn.net/sxf1061926959/article/details/84332081

兩片文章有異曲同工之妙,利用用戶點擊的session來預估下次點擊的item,而雅虎這篇將輸出的不是item而是直接輸出預測的embedding,然後直接將該embedding和所有的文章進行比較相似度,這可以說是工業落地的一個優化吧。還有Session-based Recommendations with Recurrent Neural Networks 》文章的輸入是直接輸入的id,或者將id做embedding一起訓練,但是這樣就沒有了類別信息,雅虎這篇單獨利用自編碼器硬生生把類別信息給加到embedding裏,可以說是比較6的。我說小米你說6~~~~

完結。

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章