1. 程式人生 > >淘寶雙十一的深度召回框架

淘寶雙十一的深度召回框架

阿里技術團隊有一篇文章,是講淘寶雙十一背後的支援系統的:一天造出10億個淘寶首頁,阿里工程師如何實現?。我對裡面提到的深度召回框架還挺感興趣的,試圖從中解析一下看看。

從Graph Embedding開始

阿里的這個深度召回系統來源於《DeepWalk: Online Learning of Social Representations》。我們今天先來看看這篇文章講了什麼。

DeepWalk本身是一個學習網路中頂點的embedding表達的圖演算法。它使用語言模型的方法來學習社交網路中的頂點的隱藏表達,並獲得了很好的效果。總之,DeepWalk輸入是一個網路,輸出是各個頂點的latent表達。

Problem Formulation

首先定義一些符號:G = (V, E)是一個有向帶權圖,V和E分別表示頂點和邊集。G_L = (V, E, X, Y)是一個部分有標籤的社交網路圖,其中X \in R^{|V| * S}S是特徵空間的維度。Y \in R^{|V| * \gamma}, \gamma是label集。在一般的分類演算法中,我們試圖尋找一個map將X的特徵對映到\gamma。而在這篇文章中,我們使用無監督方法來學習網路結構。

我們的目標是學習一個X_E \in R^{|V| * d},d是隱向量維度並且很小。這個d維向量代表了網路結構特徵。這個表達應該有如下特性:

  • Adaptability:新的item加入時不需要全部重新訓練
  • Community aware:兩個embedding之間距離的遠近應該能用於衡量原始item之間的相似度
  • 低維度
  • Continuous:在連續空間內取值

Random walk

隨機遊走是常見的取樣方法,本文中將它用於序列取樣。文中的隨機遊走過程如下:從頂點v_i開始的一次隨機遊走被標記為W_{v_i} = \{W_{v_i}^1, W_{v_i}^2, ..., W_{v_i}^k\},那麼下一步要選擇的頂點W_{v_i}^{k + 1}是從頂點v_k的鄰居中隨機選擇的。文章用這種方法完成取樣並且將取樣完成的序列當作語言模型中的語料來使用。

Language Model

一般來說,一個語言模型的預測目標是一個單詞在一段預料中出現的概率,即給定一個單詞序列:W_1^n = (w_0, w_1, ..., w_n),我們需要通過最大化Pr(w_n | w_1, ..., w_{n-1})來預測w_n。類比到我們的問題中,則應該是最大化Pr(v_i | (v_1, v_2, ..., v_{i-1}))。但我們的目標是學習一個隱表達,設我們所需要的map為\phi,那麼我們需要最大化Pr(v_i|\phi(v_1), \phi(v_2), ..., \phi(v_{i - 1}))。而新的語言模型允許我們不考慮詞語之間的順序,把這個問題變成:

minimize ~ -logPr({v_{i - w}, ..., v_{i - 1}, v_{i + 1}, ...,v_{i + w}}|\phi(v_i))

其中w是視窗大小。在這種設定下,擁有類似鄰居的節點會有相近的embedding表達。

Method

根據上述理論,DeepWalk的演算法如下:

其中, t是每一次random walk的長度。

首先, 隨機初始化\phi。從V建立一顆二叉樹,這主要是為了做hierarchical softmax。之後進行\gamma輪在V上的隨機遊走,每一次都需要打亂V的頂點的訪問順序。每一輪V上的隨機遊走由從每一個頂點開始的一次長度為t的隨機遊走構成。在每一個隨機遊走序列形成以後,需要使用一次Skip-Gram演算法。

Skip-Gram是一個語言模型,該模型用於最大化一個視窗內的單詞的共現概率,我們在這裡用於更新\phi。具體來說,作者們運用了hierarchical softmax方法來優化完成Skip-Gram過程,並用隨機梯度下降方法來完成更新。關於Skip-Gram,有興趣的讀者可以看這個blogWord2Vec Tutorial - The Skip-Gram Model

淘寶對DeepWalk的改造

那麼,還是根據一天造出10億個淘寶首頁,阿里工程師如何實現?我們該怎麼把DeepWalk這個模型用到淘寶推薦系統中來呢?

生成網路

DeepWalk是一個在網路上生成embedding的模型,我們首先要生成一個網路。阿里使用SWING演算法生成了一個商品之間的有向帶權圖作為網路。SWING其實是一個在u-i二部圖上,利用一種叫做SWING的三角結構生成i-i相似度的方法,如果不會用SWING的話,應該用其他的相似度模型也可以代替這個演算法。 SWINGF演算法生成的i-i相似度不是對稱的,所以最終形成的形式是有向帶權圖。

當然,有向帶權圖還意味著我們在random walk的時候需要根據權重對random walk進行調整。

對商品網路進行Random Walk取樣

文章說他們借鑑了Node2vec: Scalable Feature Learning for Networks的取樣方法。那麼,這篇文章的取樣方法是什麼呢? node2vec本身是一個用於學習網路中節點的特徵表達的半監督學習方法。它的流程其實跟DeepWalk很像。阿里在這裡主要借鑑了它的random walk的流程。

首先,我們分別定義DFS和BFS鄰居,如圖所示:

BFS鄰居是指和節點直接相連的鄰居節點;DFS鄰居指的是sequence的鄰居。BFS很容易理解,為什麼要有DFS鄰居這個定義呢?

網路中的節點有兩種相似性:一種是趨同性,比如u和s1,一種是結構相似性,比如u和s6。BFS鄰居有助於探索趨同性,而DFS鄰居有助於探索結構相似性。在商品推薦中,啤酒和紅酒可以認為是結構相似性,而啤酒和炸雞可以認為是趨同性(我自己認為的,可能有誤解)。在實踐中,這兩種相似性都很常用。Node2vec定義了同時可以運用這兩種屬性的random walk機制:

  • 一般的random walk將選擇下一節點的概率定義為正則化的轉移概率。即P(c_i = x| c_{i - 1} = v) = \begin{cases} \frac{\pi_{uv}}{Z}& \text{if }(v, x) \in E\\
0& \text{otherwise}\end{cases}
  • 而這個random walk設計了一個bias引數。假如random walk剛從節點t走到節點v,並將下一個訪問的節點記為x,令\pi_{vx} = \alpha_{pq}(t, x) * w_{v,x},且\alpha_{pq}(t, x) = \begin{cases} \frac{1}{p}& \text{if }d_{tx} = 0\\
1& \text{if }d_{tx} = 1 \\
\frac{1}{q}& \text{if }d_{tx} = 2\\
\end{cases}
  • 即設定p為回訪引數,隨機遊走以\frac{1}{p}的概率返回節點t;設定q為遠端訪問引數,q越小越傾向於訪問二度節點

除了random walk之外,node2vec還使用了negative sampling方法,用來取代DeepWalk中的hierarchical softmax方法。淘寶也同樣採用了這個方法。同時,他們還採用了動態取樣器的優化方式。關於Negative Sampling,有興趣的讀者可以看這個部落格Word2Vec Tutorial Part 2 - Negative Sampling.

進一步優化

在上述基礎上,淘寶提出了Sequence+Side-information版本。

就我的理解,所謂sequence,即用真實的使用者session資料取代random walk的資料,作為訓練樣本。不過在這裡,淘寶這個網站的特殊性是很重要的。作為一個實時更新的購物網站,使用者的瀏覽記錄之間有非常強的相關性,但是一般的網站可能相關性沒有這麼強,實踐中能不能這麼做依然存疑。

Side Information就比較好理解了,就是相當於加入一些item本身相關而structure無關的資料,加入embedding一起做訓練。畢竟我們的目標是做item召回,而不是像Deep Walk那樣想衡量社交網路上的相關性。

“在session內行為構建全網圖後,引入類似tf-idf的轉移概率連線邊,克服哈利波特熱點問題,且在此基礎上進行概率取樣,構建使用者行為的"虛擬樣本",以擴大後面輸入到深度模型裡面的寶貝覆蓋量及準確度,使多階擴充套件資訊更加完善”這一段我其實沒怎麼理解,如果有理解了的讀者歡迎交流。

最後一個階段的優化其實是針對淘寶的大規模資料集的,在一般的推薦場景下很可能不需要考慮這部分的優化,當然相對於雙十一這種規模的體量,這是非常重要的一部分。

總結

總而言之,淘寶的深度召回框架大概流程如下:

  1. 基於SWING或者任何一個i-i relevance table演算法生成一個同構網路圖
  2. 在這個網路圖上根據node2vec進行random walk,收集訓練樣本
  3. 步驟1和2也可以用真實使用者的session資料代替
  4. 在projection layer加入side information
  5. 執行Skip-Gram演算法

ps:

關於Skip-Gram我覺得還有幾個blog也寫得很好,不過有些是國外部落格的中文翻譯: