論文|看騰訊如何玩轉實時推薦-TencentRec

今天要分享的一篇論文是有關騰訊如何利用協同過濾(Collaborative Filtering)、基於內容和圖進行實時推薦的,我們都知道協同過濾是傳統的推薦算法,但在實際應用中取得的效果卻很好,因此在各大公司應用的也非常廣泛。

協同過濾的改進經常出現了各種碩士研究生的畢業論文中,那都屬於學術界的研究和實現,且是離線的,在工業界的CF算法實現和如何實時基於CF進行推薦的資料卻是少之又少,接下來的內容將會帶領你真正瞭解一下騰訊是如何在工業界進行實時的CF推薦。這裏把論文中涉及算法和架構稱之爲 TencentRec框架

論文(TencentRec Real-time Stream Recommendation in Practice)獲取,公衆號(搜索與推薦Wiki)內回覆【TencentRec】獲得。

背景

其實本篇文章的開篇也簡單說明了TencentRec的背景,接下來再補充說明一下。

推薦系統在工業界應用的十分廣泛,但在大數據背景下,如何將實時、準確度結合在一起卻十分的難,因爲這幾者本身是互斥的。而騰訊技術團隊則基於Storm,並設計研發了相關架構優化了ItemCF、ContentBased、Graph幾種算法解決了推薦系統中的大數據、實時性、準確度的問題。

架構概述

平臺選擇

在騰訊內部,日活用戶早已突破了1億(2015年),每天產生的用戶行爲數據達到了PB級別,爲了處理龐大的數據,一個分佈式的數據計算集羣是不可或缺的,對於計算平臺的選型有三點要求:

  • 能夠進行實時計算
  • 線性伸縮且可擴展
  • 具有一定的容錯能力

在調研了Yahoo S4,Spark Streaming和Storm之後,選擇了Storm作爲計算平臺,主要是因爲以下三點:

  • Storm支持實時數據流計算
  • Storm具有良好的可擴展性,可以動態增加或者刪除集羣中的節點
  • Storm具有容錯功能,可快速的進行故障恢復

下圖簡單說明了Storm集羣的架構

Structure of Storm Cluster

數據處理

TencentRec框架設計的目的是作爲一個通用的推薦框架,並應用在各種應用中。因此一個關鍵的因素是如何處理不同應用的非格式化的龐大的數據,因此研發了一個Tencent Data Acess模塊,提供數據收集和分發的接口,並把數據源和數據處理系統進行解耦。

The Architecture of TDAccess

上圖展示了TDA(Tencent Data Acess)的架構,將發佈/訂閱模型作爲通信模型。生產者是各個應用,消費者是數據處理系統。數據服務器(Data Server)負責數據緩存、數據的發佈和訂閱、生產者和消費者之間的通信。

上圖展示了兩個Master服務器(Active、Standby),Standy是備用服務器,當Active的服務器出現宕機或者故障的時候能夠代替,從而保證系統的穩定性和可用性,這一點的設計和Yarn集羣是類似的。

設計和實現TDAccess的關鍵因素如下:

  • 數據服務器不需要共享由主服務器管理的數據狀態
  • 在缺少計算資源或者需要歷史數據進行離線計算的情況下會把數據換存在硬盤上
  • 爲了實現更好的並行,將數據換存在機器上的許多分區上

狀態數據存儲

Storm由於是一個無狀態的系統,因此具有強大的緩存能力,但是推薦系統需要保持記錄的歷史數據的狀態,最直接的解決辦法是將狀態數據和程序一起存儲在程序中,但是這將導致以下問題:

  • 限制了程序的設計。不同的工作人員需要不同的狀態數據,因此需要在程序中管理狀態數據的分配和轉換,同時需要保證數據的一致性。
  • 降低系統的健壯性。如果機器無法保證狀態數據將會導致錯誤的計算結果。

爲了解決這些問題,設計了基於內存的分佈式鍵值數據存儲模塊(Tencent Data Store, TDS)用來保存推薦計算中使用的狀態數據。通過這種方式,保證了TencentRec的魯棒性,Storm保證程序的運行,TDS保證狀態數據的恢復。

The Framework of TDStore

上圖展示了TDS的架構,圖中分爲兩部分:

  • 配置服務器:由主機配置服務器和備份配置服務器組成,它們管理路由表並跟蹤數據服務器。
  • 數據服務器:負責數據存儲,支持內存數據庫(MDB),級別數據庫(LDB),Redis數據庫(RDB)和文件數據庫(FDB)存儲引擎。每個實例數據都有多個備份。

算法設計

爲了實現可擴展的推薦,實時推薦系統中常用的方式是進行數據採樣,以此滿足在有限的計算資源內產生推薦,但會降低結果的準確性。因此將所有數據都應用在計算中則是必須的。出於這樣的考慮,將傳統的推薦算法進行了分佈式實現。

ItemCF實現

由於篇幅的限制,論文中只介紹了ItemCF的詳細實現。首先回顧一下CF的思想,CF算法包括:

  • UserCF:首先計算出用戶的相似用戶,再把相似用戶有行爲的物品推薦給用戶
  • ItemCF:首先計算出物品的相似物品,再把用戶有行爲物品的相似推薦推薦給用戶

爲了在實踐中使用ItemCF算法,同時滿足“大數據”、“準確度”、“實時性”三方面的要求,主要考慮以下三方面的優化:

  • 隱式反饋優化問題
  • 可擴展的增量更新機制
  • 實時修剪技術

傳統的ItemCF

傳統的ItemCF算法分爲:物品的相似度計算和產生推薦兩步。具體的算法邏輯這裏就不解釋了,感興趣的可以閱讀:https://blog.csdn.net/Gamer_gyt/article/details/51346159

物品的相似度計算公式如下(公式1.1):
sim(ip,iq)=ipiqip2iq2=uUru,pru,qru,p2ru,q2 sim(i_p,i_q) = \frac{ \vec{i_p} \cdot \vec{i_q} } { \left \| i_p \right \| ^2 \left \| i_q \right \| ^2} = \frac{ \sum_{u \in U} r_{u,p} r_{u,q} }{ \sqrt{r_{u,p}^2} \sqrt{r_{u,q}^2} }

預測用戶對物品的評分如下(公式1.2):
ru,q^=iqNk(ip)sim(ip,iq)ru,iqiqNk(ip)sim(ip,iq) \hat{r_{u,q}} = \frac{ \sum_{i_q \in N^k(i_p)} sim(i_p,i_q) r_{u,i_q} }{ \sum_{i_q \in N^k(i_p)}sim(i_p,i_q) }

隱式反饋優化

精準的推薦算法通常需要根據用戶對物品的評分來捕獲用戶對物品的偏好,但是在實際情況下,並非總是可以獲取明顯的反饋。大部分都是隱式反饋,即間接反應用戶對物品的喜好程度。

在騰訊內部的場景中,用戶對物品的行爲包括點擊,瀏覽,購買,共享,評論等。不同的用戶行爲代表着不同程度的用戶興趣,並且應該對推薦算法產生不同的影響。因此,我們爲不同的動作類型設置了不同的權重(例如,點擊行爲計作一分,購買行爲計作三分)。如果一個用戶對一個物品表現出了多種行爲,我們將最大權重的行爲權重值作爲用戶對物品的評分,這樣可以減小各種凌亂的隱式反饋帶來的噪音。

用戶對物品ip,iqi_p,i_q的協同評分被定義爲用戶對物品評分中的最小權重值,如下公式所示(公式1.3)
co_rating(ip,iq)=min(ru,p,ru,q) co\_rating(i_p, i_q) = min(r_{u,p}, r_{u,q})
其中ru,pr_{u,p}表示用戶uu對物品ipi_p的行爲中的最大權重值。

則物品ip,iqi_p,i_q的相似度被重新定義爲如下公式(公式1.4):
sim(ip,iq)=uUmin(ru,p,ru,q)ru,pru,q sim(i_p, i_q) = \frac{\sum_{u \in U} min(r_{u,p}, r_{u,q})}{ \sqrt{\sum_{r_{u,p}}} \sqrt{\sum_{r_{u,q}}}}

可擴展的增量更新機制

在傳統的推薦系統中,協同過濾算法會採用定期更新的機制,但這種策略並不難滿足實時推薦系統的需求,因爲在TencentRec中設計了可擴展的增量更新機制。

在論文【Scalable collaborative filtering using incremental update and local link prediction】中,作者提出了一種用於連續顯式評級的基於增量項的CF方法,受這種增量更新機制的啓發,TencentRec在實踐中將相似度的計算分爲三個部分。

首先物品ip,iqi_p, i_q的相似度定義爲(公式1.5):
sim(ip,iq)=pairCount(ip,iq)itemCount(ip)itemCount(iq) sim(i_p, i_q) = \frac{pairCount(i_p, i_q)}{ \sqrt{itemCount(i_p)} \sqrt{itemCount(i_q)}}

其中:
itemCount(ip)=uUru,p itemCount(i_p) = \sum_{u \in U} r_{u,p}
pairCount(ip,iq)=uUco_rating(ip,iq) pairCount(i_p, i_q) = \sum_{u \in U} co\_rating(i_p, i_q)

公式1.5 和 公式1.4的定義是一樣的。

在公式1.5中,物品的相似度可以通過$ pairount(i_p, i_q)、itemCount(i_p)、itemCount(i_q)$進行計算,而這三項也可以很自然的進行更新。我們可以獨立的計算這三項的新增值,並將這些值融合道公式1.5中重新計算相似度。

計算的表達式如下(公式1.6):
sim(ip,iq)=pairCount(ip,iq)itemCount(ip)itemCount(iq)=pairCount(ip,iq)+Δco_rating(ip,iq)itemCount(ip)+Δru,pitemCount(iq)+Δru,q sim(i_p, i_q)' = \frac{pairCount(i_p, i_q)'}{ \sqrt{itemCount(i_p)'} \sqrt{itemCount(i_q)'}} \\ = \frac{pairCount(i_p, i_q) + \Delta co\_rating(i_p, i_q)}{ \sqrt{itemCount(i_p) + \Delta r_{u,p}} \sqrt{itemCount(i_q) + \Delta r_{u,q}}}

其中sim(ip,iq)sim(i_p, i_q)'表示新的物品間相似度。

整個實時更新的計算流程圖如下所示:

The Multi-layer Item-based CF

實時修剪技術

在ItemCF算法中,如果用戶傾向於對兩個物品進行評分,則將其視爲相關。這裏設置了鏈接時間,即在鏈接時間內有行爲的兩個物品才視爲相關。在騰訊內部,每天有很多用戶物品的行爲記錄,以新聞爲例,平均每個用戶每天會對十個以上的新聞產生行爲,如果把新聞之間的鏈接時間設置爲6個小時,則對出現在6個小時內的新聞構建物品對。

對於大多數情況,比如電商網站,鏈接時間通常設置爲3天或者7天,每個用戶操作會生成近一百個物品對,此時,每個用戶的操作都會導致數百次計算,由於大部分物品對並不相似或者沒有那麼相似,因此大多數操作是沒有必要的,會浪費大量的計算資源。

爲了解決這個問題,TencentRec基於霍夫邊界(Hoeffding Bound)理論開發一種實時修剪技術。其表達爲:xx表示
實數RR範圍內的一個實數值(在相似度中範圍市0-1),假設對該變量進行了nn次獨立觀察,並計算出了他們的均值x^\hat{x},霍夫邊界以1δ1-\delta的概率認爲該變量的真實均值最大爲:x^+ϵ\hat{x} + \epsilon,其中$\epsilon $爲(公式1.7):
ϵ=R2ln(1/δ)2n \epsilon = \sqrt{ \frac{R^2 ln(1/\delta)}{2n}}

其中δ\delta需要自己進行設定,在實踐中x^\hat{x}tt代替。

ItemCF的實時修剪算法如下:
Item-based CF Algorithm with Real-time Prun- ing

數據稀疏性問題

在真實的實踐中,數據往往是非常稀疏的,在進行計算時,會消耗大量的計算資源,也會影響推薦系統的效果。TencentRec採用了兩種機制來解決數據的稀疏性問題:

  • 人口統計聚類:根據用戶的屬性(例如年齡、性別、學歷)將其分爲不同的組。通常認爲不同的組內具有相同的興趣偏好。在不同的組內運行推薦算法,往往能獲得更加準確的結果。

User-item Matrix in Big Data Era

  • 基於人口統計學的補充:對於歷史行爲數據很少的用戶,TencentRec提出了基於人口統計學的算法以進一步完善推薦結果,旨在根據用戶羣向用戶進行推薦。具體來說,我們會計算每個用戶所屬組的熱門物品,即該組中最受歡迎的物品推薦給用戶。

實時過濾機制

在類似TencentRec的實時推薦系統中,推薦結果會不斷的發生變化,我們利用兩種技術來捕獲用戶的實時興趣,包括:滑動窗口和實時個性化過濾。使用滑動窗口技術捕獲全局實時趨勢,並使用實時個性化過濾來滿足個人用戶的實時需求。

滑動窗口技術是實時數據計算流中用於丟棄舊數據的一種常用技術,滑動窗口處理當前時間窗口中的數據,然後丟棄一小部分,繼續處理接下來的一部分數據。在TencentRec中將時間窗口劃分爲幾個會話,並且在相似度計算中只考慮了最近的WW個會話,例如在滑動窗口內計算實時ItemCF算法中的pairCountitemCountpairCount、itemCount,計算公式如下(公式1.8):
sim(ip,iq)=wWpairCountw(ip,iq)wWitemCountw(ip)wWitemCountw(iq) sim(i_p, i_q) = \frac{ \sum_{w \in W} pairCount_w(i_p, i_q)}{ \sqrt{ \sum_{w \in W} itemCount_w(i_p)} \sqrt{\sum_{w \in W} itemCount_w(i_q)}}
通過這種方式,用戶可以自定義滑動窗口的大小和會話個數。

除了滑動窗口技術之外,還提出了一種實時的個性化過濾技術來滿足不同用戶的個性化需求。 對於每個用戶,記錄他最感興趣的kk個物品。因爲隨着時間的流逝,我們認爲用戶只對最近的kk個物品感興趣。因此在考慮用戶對未知物品的評分時,只考慮有行爲的最近kk個項目即可。

在ItemCF算法中,如果計算的物品對之間相似度過低時,可以採用基於組內熱門數據補充的方法進行補充。

實現細節

實現細節這裏就不着重說了,但需要注意的有兩點:

  • 行爲爆發:在某些特殊的時間節點,用戶對物品的行爲數據要比以往更高。具體的解決辦法是,採用流分組技術將相同的key映射到一個機器上,確保緩存的有效性,如果有其他程序需要讀取數據,首先從緩存中讀取,然後再進行緩存和TDS中的數據更新。
  • 熱門物品:採用組合器技術來解決熱門物品的問題。即對相同健值對的記錄進行部分合並,合併的操作包括:增量、加法、最大化。

當然這裏還提到了一些其他的優化技巧,比如多重哈希技術,即保證同一用戶的操作分配給一個機器,繼而保證數據更新的準確性。

實踐效果

TencentRec在自己內部的很多產品上進行了上線測試,涉及的產品有:
Some Applications Applying TencentRec

爲了評估TencentRec的效果,採用了ABTest,其base組是:離線計算或者近實時計算,沒有實時過濾機制,而實驗組的話就是論文中主要描述的TencentRec,經過一個月的實驗,對錶效果如下:

Overall Performance Improvement

在新聞網站上實驗一週後的數據效果如下:
CTR of Tencent News in One Week

在易迅網上的兩個推薦位進行對比的結果如下:
CTR of Similar Price Recommendation in YiXun

CTR of Similar Purchase Recommendation in YiXun

好了,到這裏這篇論文的分享已經完了,通過這篇論文我們可以學到很多思路,可以應用到我們實際的生產環境中,當然對於離線的ItemCF算法Spark中也有實現-ALS算法,感興趣的可以閱讀這兩篇文章:

如果你覺得這篇文章不錯,請分享給更多人!

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