2018年KDD的best paper讀書筆記
0.寫在開篇的嘮嘮叨叨
- 最近老大讓我準備分享一下最近讀的論文,其實自己有在《Real-time Personalization using Embeddings for Search Ranking at
Airbnb》這篇論文和多臂老虎機的幾篇論文裏面糾結,想着分享哪一個主題更好。最後分享這篇的原因完全是衝着best
paper的title,但是從需要和人進行分享的角度開始來讀這篇論文之後,覺得作者的好多思路都好有意思,蠻適合實際的工程應用的。想法直觀,結果有效,這算是我拜讀這篇論文之後的最大感受吧。
這篇博客就是按照我自己分享的邏輯來記錄的。 - 整篇論文中的listing就是指airbnb中的一個房源
- 這篇論文主要是推薦系統的排序算法,是基於已經有一個召回的結果來對房源進行排序展示。
1.背景介紹
1.1 場景
在Airbnb中用戶通過搜索界面點擊了一個房源之後,有兩種方式繼續瀏覽其他房源:
- 返回搜索結果頁;
- 所查看房源詳情頁下的“相似房源”;
其實這兩個部分都是需要涉及到使用推薦算法來對已經召回的房源進行排序展示的。所以這篇論文是對不同的需要排序的場景來進行構建embedding的。
1.2 論文內容
論文的寫作思路就是從下面三個方面進行推進的
- 需要構造哪些embedding
- 如何構建embedding
- 如何應用embedding在這兩個場景實現更加精準的實時個性化
這篇博客也是按照這個思路來記錄。
首先回答第一個問題,需要構造哪些embedding。論文首先針對了房源詳情頁下面的“相似房源”這個應用場景提出了listing embedding,進一步爲了更好的實現搜索頁上的排序算法,又提出了user type & listing type embedding。所以可以概括爲本文提出了兩種embedding:
listing embedding + user-type & listing-type embedding
2.listing embedding
2.1 概述
- 以用戶的點擊行爲作爲序列,通過這種點擊序列的上下文關係來挖掘用戶點擊這些房源之間的內部聯繫。
- 落腳於“當前”產生的點擊行爲,所以刻畫的是用戶的短期興趣。
- 實現推薦當前點擊的listing的相似房源,session內的個性化。
- 實驗結果表明這種embedding方式能夠提取到房源的價格、類型等特徵。
2.2 數據處理
- 過濾噪聲點擊:被點擊的listing的詳情頁停留時間小於三十秒的會被過濾。
- 劃分session:用戶連續兩次點擊之間的時間超過三十分鐘,這個序列就會被劃分開到兩個不同的session中。
2.2 層層遞進的構造listing embedding的過程
step1. 使用skip-gram構造最初的目標函數
表示一個listing
step2. 採用negative sampling構造採樣之後的目標函數
表示位於當前作用center的這個listing的embedding向量
表示center後面的這個輸入listing的embedding向量
表示當前的輸入向量
表示當前的輸入向量屬於正樣本
表示當前的輸入向量屬於負樣本
由於前面兩個基礎目標函數,屬於日常比較常用的,而且後面開始纔是作者針對airbnb的實際場景提出的比較有意義的地方,所以前面兩個公式這裏就直接略過了,不做解釋。
step3. 根據預定行爲構造有導向於“booking”的目標函數
作者指出,用戶一直瀏覽的最終的目的是爲了產生“booking”這樣下訂單的行爲,因此應當將“booking”了的listing當作這一段時間(我理解的就是上一個有booking行爲到這個booking行爲之內的所有session)的最後一個item。也就是將這個booking listing當作一個全局“global”的值。在這樣的基礎上,構造了下面的目標函數
表示booking listing的embedding向量
注意藍色框的地方就是添加進來的booking listing。
由於這個booking listing是作爲“正例”樣本,所以納入到目標函數中的分母的指數是取“負”。
同時,這個booking listing納入目標函數的前面並沒有加這個求和符號,就是體現了“global”的效果,也就是在這個session裏面,都需要考慮到這個booking listing作爲正例。
這附圖應該更容易理解到這個“global”的形式:
step4.根據房源地區進一步優化得到最終的目標函數
由於listing embedding是基於當前已經點擊了一個房源,因此,此時用戶是已經有一個地區傾向了;同時,listing embedding更多的就是爲了解決airbnb的“相似房源”這個場景下的候選listing的排序,因此作者提出了在目標函數中在加入基於地區的採樣。
表示當前地區的listing的embedding向量
表示當前的輸入向量屬於目標地區中負樣本
這裏將與點擊listing處於同一個地區的其他listing當作負樣本,納入目標函數中。所以納入到目標函數中的分母的指數是取“正”。
2.3 解決冷啓動listing
由於新的房源沒有歷史被點擊的信息,所以這裏會通過找到三個地理位置最接近、房源類別和價格區間相同的“老”房源,通過計算這些“老”房源的embedding的平均值來當作“新”房源的embedding值
2.4 這樣構造listing embedding來代表listing是否有效?
作者用了三種方式來驗證這樣的embedding方式代表一個listing是有效的:
1. kmeans聚類
作者根據已有的用戶點擊數據計算了California的所有listing的listing embedding向量。
然後將這些listing embedding直接進行聚類。
最後根據聚類結果,繪製得到了這幅圖。
從圖中可以看到,地理位置接近的listing會被聚集在一起。
結論:說明這樣計算得到的embedding能夠提取地理位置上的信息
2. 分類計算平均餘弦相似度
同樣的,先根據已有的用戶點擊數據計算計算所有listing的listing embedding向量;
然後,根據listing本身的房源類型或價格區間進行分類;
最後計算分類之後的,所有listing embedding向量之間的平均餘弦相似度,得到下面兩個表。
從表中可以看到,每種類型都是對自己這個類型的房源embedding向量有最大的相似性
結論:說明listing embedding裏面能夠encode到房源的類型和價格區間這兩種features
3.k-nearest
作者還計算了每個listing embedding的k近鄰,並對比這個listing和k近鄰;
爲了展示這個結果,作者還做了一個可視化的工具來展示,這裏給了一個截圖。
可以從圖中看到,輸入一個listing embedding得到的k-nearst的房子風格都非常相似。
結論:說明embedding能夠提取房源的建築風格
2.5 離線測評
橫座標:處於book行爲發生前點擊的次數
縱座標:book的listing在該模型下處所處的位置(值越低說明排序位置越高)
- search ranking是原有的排序模型。
- re-ranking:另外三個模型對應了前面用到的三種不同目標函數提取到的embedding在search ranking上的re-ranking。
- d32 regular:採用negative sampling進行訓練的方式得到的embedding結果
- d32 booking global:在d32的基礎上加上了“book”listing作爲一個全局的上下文
- d32 booking global + market negative:在上一個模型的基礎上又加入了房源的地區來作爲負抽樣
作者將listing ID embedding到32維的向量上進行的離線測評。
整個測評思路:比較不同的“模型”,對booking的房源所排的位置的結果比較。
基於整個點擊序列往booking行爲之前回溯,取一定次數之內的所有數據。這裏作者就是取了booking前的17次點擊行爲內的listing。在原有的search ranking排序模型上,進行re-ranking,看處於“當前”的這個點擊listing下,模型計算出來最後booking的房源的位置。(這裏作者並沒有仔細說如何進行的re-ranking,我自己猜測的是將search ranking的結果計算listing embedding的餘弦相似度,然後根據整個餘弦相似度進行排序,完成推薦)
最後從圖中可以看到,re-ranking之後,booking listing的位置都往前排了。同時,也能看出來,採用“d32 booking global + market negative”這個方法構建目標函數得到的embedding,最後的位置也是最好的。
2.6 線上結果
- 應用場景:房源的詳情頁上的“相似房源”
- 應用方式:在同地區的候選listing中,計算當前點擊listing的embedding值餘弦相似度的k-nearest
- 效果:k=12,通過A\Btest發現,embedding方式能夠提高21%的點擊率,預訂訂單量增加了4.9%
3.user-type & listing-type embedding
3.1 問題引入——搜索階段如何實現cross market的長期興趣偏好的挖掘?
-
listing embedding不能夠解決的問題:
- 需要基於當前的點擊來計算
- 只提取了用戶的短期興趣
- 只能用於“相似房源”場景中
- 只針對同地區下的用戶興趣房源的挖掘
-
解決方案:
- 引入user和listing一起來構建embedding
- 不侷限區域,利用用戶所有的歷史行爲(但最終目標是爲了能夠讓用戶下訂單,所以從“booking session”來入手)
BUT
- 直接將user和listing進行建模存在的問題:
- booking session遠遠少於click session
- 大量的用戶歷史book的量非常少,可能他們的booking session的長度只有1
- 大量的listing沒怎麼被book到,但是skip gram 中對物品出現頻率是有要求的
- 對於用戶而言,兩次booking之間的時間間隔可能非常的長,但這期間,用戶的長期興趣可能已經改變了
- 解決方式:
- 針對前三個數據稀疏問題——將listing映射爲listing-type
- 針對第四個問題——將用戶映射爲user-type
3.2 數據處理
step1. 從user和listing到user_type和listing_type
分別完成user和listing到user_type和listing_type上的映射
具體的映射方式,如下:
For example, for a user from San Francisco with MacBook laptop, English language settings, full profile with user photo, 83.4% average Guest 5 star rating from hosts, who has made 3 bookings in the past, where the average statistics of booked listings were $52.52 Price Per Night, $31.85 Price Per Night Per Guest, 2.33 Capacity, 8.24 Reviews and 76.1% Listing 5 star rating, the resulting user_type is
這樣就實現了將所有的用戶和房源都進行了聚合。
作者還強調,用type來表示原有的user和listing,可以解決兩個問題:
- 實時個性化的體現:即使時同一個listing或user會因爲用戶行爲的發生,對應的type也會隨着改變。
- 冷啓動問題:用戶層面上的前五個特徵是通用的畫像特徵,對於新用戶可以直接通過這五個特徵完成映射。
step2. 獲取booking session
只提取預定行爲,按時間構造booking session
step3. 構造輸入數據
按時間構造形如(user-type, listing-type)的二元組所構成的有序序列,表示該user_type預定了該listing_type。
作者指出,按照這樣形式構造輸入序列的原因是爲了將user-type和listing-type都映射到同一個特徵空間中。
3.3 層層遞進的構造type embedding的過程
step1. 使用negative sampling構造最初的目標函數
同樣的,在type embedding的構造過程中,用negative sampling作爲最基礎的目標函數。
- user_type embedding
- listing_type embedding
表示當前輸入表示作用在輸入listing上的映射參數向量
表示當前的輸入向量屬於目標地區中負樣本
前面提到了,以(user_type, listing_type)的形式輸入數據進行模型訓練,以此將user_type和listing_type的embedding映射到同一個特徵空間中。所以這裏的對於同一個樣本的值是一樣的。
step2. 將房東的拒絕行爲(rejection)作爲負採樣的目標函數
book行爲完成,除了用戶主觀上想要與預定之外,還包含了房東也要接受用戶的book請求。實際情況中,也存在了用戶發出了book request但是房東reject,導致訂單沒有完成的情況。
所以,作者指出爲了刻畫訂單完成情況,減少未來發生reject現象,這裏納入了用戶發出book request行爲後是一位內房東reject導致此次book行爲失敗的情況。
我的理解是,把所有用戶主觀上想要book的記錄也納入了真實完成了booking的session中。如果這個訂單真的完成了booking,那麼這一對(user_type,listing_type)就是一個正例樣本,如果被房東reject了,(user_type,listing_type)就是一個負例樣本。
4.embedding的應用
4.1 embedding中所蘊含的信息檢查
作者計算了用戶當前所處的user_type與候選的listing的listing-type embedding之間的餘弦相似度
這裏給出了一個計算結果,對某一個屬於這類的用戶,得到餘弦相似度比較高的幾個listing type embedding,然後瀏覽了該用戶歷史上的訂單情況,發現embedding能夠概括用戶的預定偏好=>該用戶預定的房源基本都偏向於空間大,數量多,評論高的房源。
4.2 搜索排序
4.2.1 衍生embedding features
作者將embedding運用在在原有的排序算法上,衍生出embedding features實現了更好的排序效果
-
原有的排序模型:
- 算法:pairwise的支持lambda rank的GBDT
- 特徵:listing features、user features、query features和cross features
-
現在的排序模型:
- 算法:pairwise的支持lambda rank的GBDT
- 特徵:listing features、user features、query features和cross features,及新增embedding features
表中前七行特徵都是基於listing embedding做的衍生特徵,是一個短期的興趣刻畫;
最後一行UserTypeListingTypeSim基於type embedding做的特徵,是一個長期興趣的刻畫。
前七行特徵需要先根據用戶行爲計算得到一些基礎的指標、、、、、
:clicked listing_ids 用戶過去兩週內點擊過的listings id
:long-clicked listing_ids 過去兩週內用戶點擊過,同時在詳情頁面上停留時長超過60s的listing id
:skipped listing_ids 過去兩週內用戶直接忽略進而點擊了陳列在它後面的listing
:wishlisted listing_ids 過去兩週內用戶加入心願單的listing
:inquired listing_ids 過去兩週內用戶聯繫過房東但是沒有成爲book訂單的listing
:booked listing_ids 過去兩週內用戶預定過的listing
從這些基礎指標的定義以及計算方式上可以看到,這些指標是會根據用戶的行爲不斷髮生改變的,所以作者也強調,embedding features的引入能夠實現現有的排序算法實時更新。
4.2.2 具體計算步驟
- step1:準備三類embedding值(listing embedding,user_type embedding、listing_type embedding)
- step2:獲取基礎指標
- step3:提取地區embedding
因爲基礎指標都是基於用戶歷史點擊的listing計算到的,而這些listing可能位於不同的地區,所以這裏先提取H*中所包含的所有地區,然後計算每個地區所有listing embedding的均值作爲這個地區的embedding - step4:計算embedding features
- listing embedding層面:
比如說,EmbClickSim,針對每一個候選的listing,計算候選listing的listing embedding與地區embedding之間的餘弦相似度相似度,取最高值作爲該listing的EmbClickSim取值 - type embedding層面:
UserTypeListingTypeSim即計算每一個候選listing所在的listing type和當前用戶所在的user-type的type embedding之間的相似度
- listing embedding層面:
- step5:在原有的排序模型中加入embedding features進行計算
關於爲什麼要提取基礎指標,並計算地區embedding,我的理解:因爲需要了解到用戶近期的一個行爲偏好,因此需要提取近期的用戶行爲。同時,也需要用某種規則將近期的這些行爲模式提取出來;又因爲listing embedding裏面其實是蘊含了地區之間的差異信息的,因此用地區來進行分組,使得組內方差變小,平均之後的embedding更具有代表性,所以才採用了計算每個地區的listing embedding值來代表用戶對地區的偏好。
4.2.3 embedding思想在airbnb搜索系統上的測評
只存在離線測評,作者說在線測評的結果:several months later
原有features+embedding features共有104個,對數據進行擬合之後可以看到這些新生成的embedding features的重要度在104個特徵中,重要性排名挺高的。這說明了embedding features對排序算法影響蠻大的。
另一方面,直接計算了新的排序模型在DCU等指標上的值,發現加入了embedding features之後的排序模型,在所有的指標上都有提升。
5.疑惑
5.1 booking session的長度
原文中有這樣的一段話:
Specifically, we form a set consisting of booking sessions from N users, where each session is defined as a sequence of booking events, i.e. (user_type, listing_type) tuples ordered in time. Note that each session consists of bookings by same user_id, however for a single user_id their user_types can change over time, similarly to how listing_types for the same listing can change over time as they receive more bookings.
我理解的就是一個session就是一個用戶的所有booking行爲。當用戶不斷髮生預定行爲,他所對應user_type也在不斷變化,同時listing也是因爲用戶們的預定行爲一直在改變其listing_type。
對於一個有很多次預定行爲的用戶,他的session長度肯定大於1,但是對於歷史上就只預定過一次的用戶,預定長度還是1呀。
5.2 如何進行的訓練
作者提出的將user_type和listing_type映射到同一個特徵空間中,這個embedding是怎麼實現的?
就從作者給出的加入了房東reject的session示意圖中看,user_type和listing_type是平行放入了模型中,但是這樣存在一個問題就是窗口在進行滑動的過程中,中心item有時候會是user_type有時候又會是listing_type,同時,中心item的前後就會變成不同時期的另一個type,比如說,當前的中心item是但是它前面一個item就會變成後面一個item就是,我感覺用這樣的序列進行訓練不是很合理呀。