【Airbnb搜索】:Real-time Personalization using Embeddings for Search Ranking at Airbnb

原始論文下載地址:

本文是kdd 2018 的best paper,文章來自airbnb的搜索推薦團隊,描述的是airbnb如何使用embedding來提高搜索和排序的效果。

知乎有官方認證的中文文章(文章地址原始論文)。文章利用搜索的session數據來獲取Listing和用戶的embedding,全文思想相對來說還是比較簡單的,但是整體針對業務實際情況,一步步的解決問題的思路很清晰,和airbnb之前發的“Applying Deep Learning To Airbnb Search”這篇論文一樣,將他們算法應用和改進到實際業務中的探索過程都講的非常清晰,非常適合在一線開發的人員閱讀。

最後的學習type級別的embedding,其實也可以擴展用來學習冷啓動的一些embedding,不知道效果會不會也不錯。下面就開始介紹一下。

airbnb是一個雙端的房屋短租平臺,用戶通過搜索或者平臺的推薦來找到喜歡的房源。因爲一個用戶很少會預定同一個房源多次,一個房源(後面就用listing來代替)在一個時間段內只能被一個用戶租賃,所以該平臺的數據存在嚴重的稀疏問題。本文主要針對airbnb在搜索排序和推薦的實時個性化中設計了一套listing和user的embedding。embedding學習過程將搜索session中數據看作類似序列信息,並通過類似word2vec的方式學習出每個房源id的embedding值,從而在有效學習出房源的多種特徵外,還很好的結合到了自身的業務。

搜索的目標根據業務不同需求也不同。有的是爲了點擊率,有的是爲了新聞的觀看時長,還有的是爲了提高商品購買的轉化率等等。而airbnb作爲一個雙端市場,需要同時爲市場兩端用戶提高搜索的性能,即那些買(guest)和賣的(host)。這類市場的內容發現和搜索排名需要同時滿足生態系統的供需雙方,才能發展和繁榮。

在airbnb中,需要同時爲host和guest優化搜索結果,比如輸入一query,query帶有位置和旅行的時間,那麼我們就需要根據位置,價格,類型,評論等因素排序來獲得客戶喜歡的listing。進一步,還需要過濾掉那些有壞的評論,寵物,停留時間,人數,等其他因素而拒絕guest的listing,將這些listing排列的低一點。爲了解決這個問題,作者團隊採用Learnig to rank來做,將該問題形式化爲pairwise regression問題,將預定的listing作爲正樣本,拒絕的作爲負樣本。

因爲guest通常在預定前進行多次的搜索,即點擊多個listing,並且聯繫其中的多個host,這就可以進一步利用點擊,聯繫信息等等來做實時的個性化,以此來展示更多他們可能喜歡的listing。於此同時也可以進一步利用一些負反饋,比如他們跳過的排名靠前的listing,以此來減少他們可能不喜歡的listing。爲了能夠計算listing和guest之間的相似性,本文團隊採用了一個從搜索交互session中學習得到的embedding來表示listing。並利用這些相似性來爲搜索排序模型和推薦系統提供個性化特徵。

除了使用即時用戶交互的實時個性化,比如一些點擊,這些可以被認爲是用戶的短期興趣,作者還介紹了另外一種embedding方法,從預定信息中捕獲用戶的長期興趣。考慮到旅行商業的特殊性,一個用戶平均一年通常只會旅行1-2次,所以預定listing是一個很稀疏的信號,他擁有很大一塊長尾的單次預定信息。爲了解決這塊問題,作者使用用戶類型來學習用戶的embedding,而不是直接通過用戶的embedding,而這裏的用戶類型是類似於根據用戶的一些已知屬性來對用戶分成很個類別。於此同時在相同的向量空間下,學習出listing的類型embedding。這使得用戶和listing之間的相似性計算變得方便。

 

本文貢獻:

1.實時個性化:之前一些文獻做的個性化和推薦embedding都是通過離線構造user-item交互和item-item來做離線推薦。並在推薦的時候讀取數據。本文實現了用戶最近交互的item embedding是被結合到在線的方式去計算item之間的相似性。
2.適應集中式搜索的訓練方式:不像一般的網站搜索,旅行平臺的搜索都先對比較集中,比如如果是搜索的巴黎,那麼就很少會跨域進行搜索,所以爲了更好的捕獲同一市場內的listing相似性,在模型的負採樣中做了一定的優化。
3.利用轉化來作爲全局上下文:作者認爲那些以轉化成功結束(就是被預定的)的點擊session更加重要,在學習listing embedding的時候將預定的listing 作爲全局上下文,在滑動窗口在整個session中移動的時候總能被預測。
4.用戶類型embedding:之前的工作很大都是給每個id訓練一個embedding,但是當用戶行爲很稀疏的時候,是沒有辦法訓練出一個好的embedding的,而且爲每個用戶存儲embedding值,對實時計算來說,需要將embedding存儲在內存中,是相當費內存的。而我們只去學習用戶類型的embdding,這樣同一個類型的用戶就會擁有相同的embedding值。
5. 拒絕作爲明確的負反饋:所謂拒絕就是說曝光在頭部的數據,但是用戶卻沒有點或者預定,爲了儘量減少導致拒絕的推薦,作者在爲用戶和listing編碼的時候將host的喜好作爲負反饋加入到用戶和listing的embedding中。

 

Listing Embedding

訓練數據集的構造:數據集由N個用戶的點擊Session組成,其中每個session  s=(L_{1},L_{2},...,L_{n})\in S 表示的是用戶點擊的n個listing id序列。其中時間間隔超過30分鐘的,就需要被分成兩個session。給定數據集,目標就是通過集合S,學習出每個listing的d維的向量,讓相似listing在embedding空間的距離更近。這裏定義的embedding維度爲32,低緯度的設置可以在模型上線後讓實時召回的速度更快。

這裏提出的方法其實很簡單,就是類似將session看着一個句子,然後採用類似word2vec的方式把session中的每個id看着一個詞,來學習每個id的embedding。我們可以把該模型先理解爲skipgram模型。如下圖所示: 

                                     

從上圖可以看出來,相比正常的skipgram,這裏它做了一些改變,它把session中被預定的listing作爲一個全局的上下文始終出現在每次的滑動窗口中。具體的改進可以總結爲兩點:

1.使用session被預定的listing作爲全局上下文(Global Context):全局上下文什麼意思呢?其實就是比如我們在訓練skipgram的時候,學習每個詞的時候,根據設置的大小,只會選擇每個詞前後n個詞作爲正樣本,所以隨着窗口的滑動,窗口內的詞是一直在變的,而這個全局上下文就是這個listing id一直存在與該session的滑動窗口內。

2.適配聚集搜索:因爲一個人的旅行目的地通常在確定後,房源的租賃都會限制在該目的地內,因此在模型訓練時,對於正在訓練的中心listing來說,它的負樣本不應該是其他地區的listing,而應該是在同一個區域內的房源,因爲一個人只會在同一個區內進行比較不同listing的好壞。所以針對這個問題,模型在進行負採樣的時候並不是從全部的listing中抽樣,而是從訓練的中心listin的同一區域內進行隨機的抽樣作爲負樣本。

所以最終的優化目標就變成了:

                          

具體參數解釋如下:

其實整個公式,上半部分就是原始的是kipgram需要優化的目標,而下半部分爲本文加入的東西,分別爲全局上下文和同區域內的採樣。

冷啓動 Listing Embedding

冷啓動問題在任何推薦系統中都是在所難免的,對於冷啓動的Listing,這裏採用了一個近似取值的方法,即對於剛組成的Listing,獲取其原始的特徵,如位置,價格等,然後去找到其最近的三個Listing,將最近的三個Listing embedding 平均後作爲其Embedding值。這樣基本能覆蓋到98%的新Listing。

評估 Listing Embedding

爲了檢驗embedding的效果,文章用了多種方法從多個角度來進行驗證。

1.K-means 聚類,將embdding進行聚類,然後可以發現其在地理位置上的區分度。如下圖:

                                             

2. embeddng之間的餘弦距離度量

 在不同類型的listing之間計算餘弦距離,不同價格範圍的listing之間計算餘弦距離,結果如下:

                                             

效果還是有的。當然這些價格,地理位置的特徵其實都是一些基礎的屬性,是可以直接獲取的屬性,但是embedding其實不光學到來這些,而是將所有影響用戶點擊的屬性都包含在來embedding內,很多可能都無法直接度量。這裏還展示來一個他們自己研究的用來評估embedding學習紋理的工具,結果如下:

                                                    

 

用戶類型 Embedding 和Listing類型 Embedding


前面描述的Listing embedding 能很好的表達同一市場下Listing之間的相似性,所以他們很適合做短期的個性化,用於比較session內的實時推薦。但是一些長期的行爲,比如一個人在很久之前在另外一個城市預定過房間,那麼現在在當前城市很有可能還是會喜歡預定同類型的房源。所以進一步從預定的Listing中來捕獲這些信息。

構造數據集:由前面的點擊序列變成預定序列,數據集爲N個用戶預定的Listing 組成的session集合。每個sesison可以表示爲S_{b}=(l_{b1},...,l_{bM})是用戶的預定listing序列。

但是用這種方式訓練存在很多問題:

1.訓練數據集會很小,因爲相比點擊,預定的數據會小一個量級。

2.很多用戶在過去只預定過一次,這些數據是沒法用來訓練模型的。

3.需要進一步去掉那些在平臺上總共就被預定的次數很少的Listing。比如少於5-10次的Listing。

4.長時間的跨度,可能用戶的喜歡已經一些習慣已經發生變化。

爲了處理這些問題,提出了學習類型級別的embedding學習,而不是去學習id級別的embedding。給定Listing的原始數據,比如位置,價格,類型,牀位數等等,然後給定一些硬性的規則生成每個Listing的類別,如下圖 

                                                    

這樣原本稀疏的數據,將id變成類型後,很多session出現了共現。

同樣,用戶的embedding方式也用了相同的方法,將擁有一些相同的基礎屬性和相同行爲的用戶也進行了分桶,如下圖所示:

                                                      

其實可以理解爲,分別對用戶和房源做了聚類,按聚類後的數據進行學習embedding,以此來獲取粗粒度的長期興趣。

基於Embedding的實時個性化

首先,embedding的訓練是設置的訓練數據像窗口一樣,按天前進。設置好窗口大小後按天進行訓練。

實時個性化主要分兩邊,一塊是從候選集中實時對比每個候選集和用戶相關listing的相似度,再將相似度分值作爲特徵,進一步作爲排序模型的特徵,對候選集進一步重排序。

如何實時收集用戶短期行爲,aitbnb團隊採用kafka消息隊列來收集用戶的兩個歷史記錄:

  1. H_{c} : 用戶過去兩週內點擊過的Listing id
  2. H_{lc} : 用戶點擊並且停留在listing詳情頁超過60s
  3. H_{s} : 用戶過去兩週內跳過的Listing id(跳過的定義是那些排在前面但是用戶沒有點,反而點了後面的Listing)
  4. H_{w} : 用戶添加到期望列表
  5. H_{i} : 用戶聯繫了但是沒有預定
  6. H_{b} : 兩週內用戶預定的

有了這兩個規則後,就可以獲得一批Listing id,然後根據這批Listing id,利用整個Hc的embedding均值和候選集Listing 的相似度表。這樣就可以獲得每個H*和候選listing embedding的相似度,然後把這些相似度分別作爲特徵,進一步的放到後一層的排序模型中對候選集進行排序。當然最後的排序模型還用到了其他的特徵,比如用戶類型和lsiting 類型級別的embedding相似度,以及其他的一些基礎特徵等等。

 

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