天天看點

《Real-time Personalization using Embeddings for Search Ranking at Airbnb》論文總結

這次總結的文章是2018 kdd best paper,來自Airbnb的學長們。

由于從去年年底到現在一直在百度feed實習,也接觸到了大量的推薦業務,其實生成embedding更是家常便飯,今天這篇文章更是把embedding思想發揮到了極緻。

Airbnb作為全世界最大的短租網站,提供了一個連接配接房主(host)挂出的短租房(listing)和主要是以旅遊為目的的租客(guest/user)的中介平台。這樣一個中介平台的互動方式比較簡單,guest輸入地點,價位,關鍵詞等等,Airbnb會給出listing的搜尋推薦清單:

容易想見,接下來guest和host之間的互動方式無非有這樣幾種:

  1. guest點選listing (click)
  2. guest預定lising (book)
  3. 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的興趣。

  1. 一是通過click session資料生成listing的embedding,生成這個embedding的目的是為了進行listing的相似推薦,以及對使用者進行session内的實時個性化推薦。
  2. 二是通過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,我們可以把這個sequence當作一個“句子”樣本,開始embedding的過程。Airbnb不出意外的選擇了word2vec的skip-gram model作為embedding方法的架構。通過修改word2vec的objective使其靠近Airbnb的業務目标。

這裡直接列出word2vec的skip-gram model的objective如下:

《Real-time Personalization using Embeddings for Search Ranking at Airbnb》論文總結

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

《Real-time Personalization using Embeddings for Search Ranking at Airbnb》論文總結

轉移到Airbnb這個問題上,正樣本很自然的取自click session sliding window裡的兩個listing,負樣本則是在确定central listing後随機從語料庫(這裡就是listing的集合)中選取一個listing作為負樣本。

在原始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就變成了下面的樣子

《Real-time Personalization using Embeddings for Search Ranking at Airbnb》論文總結

其中最後一項的lb就是代表着booked listing,因為booking是一個正樣本行為,這一項前也是有負号的。注意,這裡的objective應該是一個滑動視窗的objective,原論文這裡可能不嚴謹(歡迎讨論)

下面這一項就比較容易了解了,為了更好的發現同一市場(marketplace)内部listing的差異性,Airbnb加入了另一組negative sample,就是在central listing同一市場的listing集合中進行随機抽樣,獲得一組新的negative samples。同理,我們可以用跟之前negative sample同樣的形式加入到objective中。

《Real-time Personalization using Embeddings for Search Ranking at Airbnb》論文總結

其中Dmn就是新的同一地區的negative samples的集合。

至此,lisitng embedding的objective就定義完成了,embedding的訓練過程就是word2vec negative sampling模型的标準訓練過程,這裡不再詳述。

除此之外,文章多介紹了一下cold start的問題。簡言之,如果有new listing缺失embedding vector,就找附近的3個同樣類型、相似價格的listing embedding進行平均得到,不失為一個實用的工程經驗。

總結起來就是,在skip-gram形勢采用負采樣訓練的word2vec中的每一個滑動視窗的損失中添加了正樣本資訊(book session中添加了book item),是搜尋清單和相似清單更加傾向于推薦之前預定過的item,又添加了負樣本資訊(central item同一市場的集合中随機負采樣)這樣更能發現同一個市場中item的差異。

我們介紹了Airbnb為了捕捉使用者的短期興趣,使用使用者的點選資料建構了listing(也可稱為item,即一個短租屋)的embedding,基于該embedding,可以很好的找出相似listing,但有所欠缺的是,該embedding并沒有包含使用者的長期興趣資訊。

比如使用者6個月前訂了一個listing,其中包含了該使用者對于房屋價格、房屋類型等屬性的長期偏好,但由于之前的embedding隻使用了session級别的點選資料,進而明顯丢失了使用者的長期興趣資訊。

為了捕捉使用者的長期偏好,airbnb在這裡使用了booking session序列。比如使用者j在過去1年依次book過5個listing,那麼其booking session就是

《Real-time Personalization using Embeddings for Search Ranking at Airbnb》論文總結

。既然有了booking session的集合,我們是否可以像之前對待click session一樣拿直接應用w2v的方法得到embedding呢?答案是否定的,因為我們會遇到非常棘手的資料稀疏問題。

具體來講booking session的資料稀疏問題表現在下面三點上:

  1. book行為的總體數量本身就遠遠小于click的行為,是以booking session集合的大小是遠遠小于click session的
  2. 單一使用者的book行為很少,大量使用者在過去一年甚至隻book過一個房源,這導緻很多booking session sequence的長度為1
  3. 大部分listing被book的次數也少的可憐,大家知道w2v要訓練出較穩定有意義的embedding,item最少需要出現5-10次,但大量listing的book次數少于5次,根本無法得到有效的embedding。

Airbnb如何解決如此嚴重的資料稀疏問題,訓練出有意義的user embedding和listing embedding呢?

他們給出的答案是基于某些屬性規則做相似user和相似listing的聚合。

那麼我們就可以用屬性名和bucket id組成一個屬性辨別,比如說某個listing的國家是US,類型(listing type)是Ent(bucket 1),每晚的價格(per night)是56-59美金(bucket3),那麼就可以用US_lt1_pn3來表示該listing的listing_type。

user_type的定義同理。

有了user type和listing type之後,一種直覺的生成新的booking session sequence的方式是這樣,直接把user type當作原來的user id,生成一個由listing type組成的booking session。這種方法能夠解決資料稀疏性的問題,卻無法直接得到user type embedding。為了讓user type embedding和listing type embedding在同一個vector space中生成,airbnb采用了一種比較“反直覺”的方式。

針對某一user id按時間排序的booking session,

《Real-time Personalization using Embeddings for Search Ranking at Airbnb》論文總結

,我們用(user_type, listing_type)組成的元組替換掉原來的listing item,是以sequence變成了

《Real-time Personalization using Embeddings for Search Ranking at Airbnb》論文總結

,這裡

《Real-time Personalization using Embeddings for Search Ranking at Airbnb》論文總結

指的就是listing l1對應的listing type,

《Real-time Personalization using Embeddings for Search Ranking at Airbnb》論文總結

指的是該user在book listing l1時的user type,由于某一user的user_type會随着時間變化,是以

《Real-time Personalization using Embeddings for Search Ranking at Airbnb》論文總結

不一定相同。

有了該sequence的定義,下面的問題就是如何訓練embedding使得user type和listing type在一個空間内了。訓練所用的objective完全沿用了上一篇文章的objective的形式,但由于我們用一個(user type,listing type)的元組替換掉了原來的listing,如何确定central item就成為了一個核心問題。看了原文章,也沒太講清楚,我猜測大機率是把元組打平了(歡迎讨論)。

接下來為了引入“房主拒絕”(reject)這個action,airbnb又在objective中加入了reject這樣一個negative signal,方法與上一篇文章中加入negative signal的方法相同,在此不再贅述。

介紹完論文之後看看airbnb中用到特征

《Real-time Personalization using Embeddings for Search Ranking at Airbnb》論文總結

清晰明了 除了最後一個特征 其他特征都是第一種embedding的産出,最後一個特征是基于使用者長興趣的特征。

最後回顧一下标題,為什麼airbnb在文章題目中強調是real time personalization?原因就是由于在這些embedding相關的feature中,我們加入了“最近點選listing的相似度”,“最後點選listing的相似度”這類特征,由于這類特征的存在,使用者在點選浏覽的過程中就可以得到實時的回報,搜尋結果也是實時地根據使用者的點選行為而改變,是以這無疑是一個real time個性化系統。

繼續閱讀