從KDD 2018 Best Paper看Airbnb實時搜尋排序中的Embedding技巧
這裡是 「王喆的機器學習筆記」 的第八篇文章,今天我們聊一聊KDD 2018的Best Paper,Airbnb的一篇極具工程實踐價值的文章 Real-time Personalization using Embeddings for Search Ranking at Airbnb 。
相信大家已經比較熟悉我選擇計算廣告和推薦系統相關文章的標準:
- 工程導向的;
- 阿里、facebook、google等一線網際網路公司出品的;
- 前沿或者經典的。
Airbnb這篇文章無疑又是一篇兼具實用性和創新性的工程導向的paper。文章的作者Mihajlo發表這篇文章之前在Recsys 2017上做過一個talk,其中涉及了文章中的大部分內容,我也將結合那次talk的slides來講解這個論文。
廢話不多說,我們進入文章的內容。
Airbnb作為全世界最大的短租網站,提供了一個連線房主(host)掛出的短租房( listing )和主要是以旅遊為目的的租客(guest/user)的中介平臺。這樣一箇中介平臺的互動方式比較簡單,guest輸入地點,價位,關鍵詞等等,Airbnb會給出listing的搜尋推薦列表:

容易想見,接下來guest和host之間的互動方式無非有這樣幾種:
- guest點選listing ( click )
- guest預定lising ( book )
- host有可能拒絕guest的預定請求 ( reject )

基於這樣的場景,利用幾種互動方式產生的資料,Airbnb的search團隊要構建一個real time的ranking model。為了捕捉到使用者short term以及long term的興趣,Airbnb並沒有把user history的clicked listing ids或者booked listing ids直接輸入ranking model,而是先對user和listing進行了embedding,進而利用embedding的結果構建出諸多feature,作為ranking model的輸入。這篇文章的核心內容就是介紹 如何生成listing和user的embedding 。
具體到embedding上,文章通過兩種方式生成了兩種不同的embedding分別capture使用者的short term和long term的興趣。
- 一是通過click session資料生成listing的embedding ,生成這個embedding的目的是為了進行listing的相似推薦,以及對使用者進行session內的實時個性化推薦。
- 二是通過booking session生成user-type和listing-type的embedding ,目的是捕捉不同user-type的long term喜好。由於booking signal過於稀疏,Airbnb對同屬性的user和listing進行了聚合,形成了user-type和listing-type這兩個embedding的物件。
我們先討論第一個對listing進行embedding的方法:
Airbnb採用了click session資料對listing進行embedding,其中click session指的是一個使用者在一次搜尋過程中,點選的listing的序列,這個序列需要滿足兩個條件,一個是隻有停留時間超過30s的listing page才被算作序列中的一個數據點,二是如果使用者超過30分鐘沒有動作,那麼這個序列會斷掉,不再是一個序列。

這麼做的目的無可厚非,一是清洗噪聲點和負反饋訊號,二是避免非相關序列的產生。
有了由clicked listings組成的sequence,就像我們在之前專欄文章中講過的item2vec方法一樣,我們可以把這個sequence當作一個“句子”樣本,開始embedding的過程。Airbnb不出意外的選擇了word2vec的skip-gram model作為embedding方法的框架。通過修改word2vec的objective使其靠近Airbnb的業務目標。

我們在之前的專欄文章萬物皆embedding 中詳細介紹了word2vec的方法,不清楚的同學還是強烈建議先去弄明白word2vec的基本原理,特別是objective的形式再繼續下面的閱讀。
我們假設大家已經具備了基本知識,這裡直接列出word2vec的skip-gram model的objective如下:

在採用negative sampling的訓練方式之後,objective轉換成了如下形式:

其中σ函式代表的就是我們經常見到的sigmoid函式,D是正樣本集合,D'是負樣本集合。我們再詳細看一下上面word2vec這個objective function,其中前面的部分是正樣本的形式,後面的部分是負樣本的形式( 僅僅多了一個負號 )。
為什麼原始的objective可以轉換成上面的形式,其實並不是顯然的,感興趣的同學可以參考這篇文章, Negative-Sampling Word-Embedding Method 。這裡,我們就以word2vec的objective function為起點,開始下面的內容。
轉移到Airbnb這個問題上,正樣本很自然的取自click session sliding window裡的兩個listing,負樣本則是在確定central listing後隨機從語料庫(這裡就是listing的集合)中選取一個listing作為負樣本。
因此,Airbnb初始的objective function幾乎與word2vec的objective一模一樣,形式如下:

(給大家出個腦筋急轉彎,為啥Airbnb objective的正樣本項前面是負號,原始的word2vec objective反而是負樣本項前面是負號,是Airbnb搞錯了嗎?)
在原始word2vec embedding的基礎上,針對其業務特點,Airbnb的工程師希望能夠把booking的資訊引入embedding。這樣直觀上可以使Airbnb的搜尋列表和similar item列表中更傾向於推薦之前booking成功session中的listing。從這個motivation出發,Airbnb把click session分成兩類,最終產生booking行為的叫booked session,沒有的稱做exploratory session。
因為每個booked session只有最後一個listing是booked listing,所以為了把這個booking行為引入objective,我們不管這個booked listing在不在word2vec的滑動視窗中,我們都會假設這個booked listing與滑動視窗的中心listing相關,所以相當於引入了一個global context到objective中,因此,objective就變成了下面的樣子

其中最後一項的lb就是代表著booked listing,因為booking是一個正樣本行為,這一項前也是有負號的。
需要注意的是最後一項前是沒有sigma符號的,前面的sigma符號是因為滑動視窗中的中心listing與所有滑動視窗中的其他listing都相關,最後一項沒有sigma符號直觀理解是因為booked listing只有一個,所以central listing只與這一個listing有關。
但這裡的objective的形式我仍讓是有疑問的,因為這個objective寫成這種形式應該僅代表了一個滑動視窗中的objective,並不是整體求解的objective。如果是整體的objective,理應是下面的形式:

其中Db代表了所有booked session中所有滑動視窗中central listing和booked listing的pair集合。
不知道大家有沒有疑問,我們可以在這塊多進行討論。
下面這一項就比較容易理解了,為了更好的發現同一市場(marketplace)內部listing的差異性,Airbnb加入了另一組negative sample,就是在central listing同一市場的listing集合中進行隨機抽樣,獲得一組新的negative samples。同理,我們可以用跟之前negative sample同樣的形式加入到objective中。

其中Dmn就是新的同一地區的negative samples的集合。
至此,lisitng embedding的objective就定義完成了,embedding的訓練過程就是word2vec negative sampling模型的標準訓練過程,這裡不再詳述。
除此之外,文章多介紹了一下cold start的問題。簡言之,如果有new listing缺失embedding vector,就找附近的3個同樣型別、相似價格的listing embedding進行平均得到,不失為一個實用的工程經驗。
為了對embedding的效果進行檢驗,Airbnb還實現了一個tool,我們簡單貼一個相似embedding listing的結果。

從中可以看到,embedding不僅encode了price,listing-type等資訊,甚至連listing的風格資訊都能抓住,說明即使我們不利用圖片資訊,也能從使用者的click session中挖掘出相似風格的listing。
至此我們介紹完了Airbnb利用click session資訊對listing進行embedding的方法。寫到這裡筆者基本要斷氣了,下一篇我們再接著介紹利用booking session進行user-type和listing-type embedding的方法,以及Airbnb如何把這些embedding feature整合到最終的search ranking model中的方法。
最後給大家三個問題以供討論:
- 為什麼Airbnb objective中正負樣本的正負號正好跟word2vec objective的正負號正好相反?
- Airbnb加入booked listing作為global context,為什麼在objective中不加sigma加和符號?
- 這裡我們其實只得到了listing的embedding,如果是你,你會怎樣在real time search ranking過程中使用得到的listing embedding?
這裡是 「王喆的機器學習筆記」 的第八篇文章,水平有限,歡迎大家拍磚、吐槽、討論。覺得有收穫的同學也歡迎點贊,謝謝。
參考資料: