旅游推薦系統的演進
背景
度假業務在整個在線旅游市場中占據著非常重要的位置,如何做好做大這塊蛋糕是行業內的焦點。與美食或酒店的用戶興趣點明確(比如找某個確定的餐廳或者找某個目的地附近的酒店)不同,旅游場景中的用戶興趣點(比如周末去哪兒好玩)很難確定,而且會隨著季節、天氣、用戶屬性等變化而變化。這些特點導致傳統的信息檢索并不能很好的滿足用戶需求,我們迫切需要建設旅游推薦系統(本文中度假=旅游)。
旅游推薦系統主要面臨以下幾點挑戰:
- 本異地差異大。在本地生活場景中用戶需求絕大部分集中在本地,而在旅游場景中超過30%的訂單來自于異地請求,即常駐城市為A的用戶購買了城市B的旅游訂單。外地人瀏覽北京時推薦故宮、長城沒有問題,北京人瀏覽時推薦北京歡樂谷、野生動物園更為合適。
- 推薦形式多樣。除了景點推薦外,還有跟團游、景酒套餐的推薦。景點下有大量重復相似的門票,不適合按Deal(團購單)樣式展示;跟團游、景酒套餐一般會綁定多個景點,又不適合按POI(門店)樣式展現。
- 季節性明顯。比如,冬季溫泉、滑雪比較熱銷,夏季更多人選擇水上樂園。
- 需求個性化。比如,親子類用戶和情侶類用戶的需求會不太一樣,進一步細分,1~4歲、6歲以上親子類用戶的需求也會有所差別。
針對上述問題我們定制了一套完整的推薦系統框架,包括基于機器學習的召回排序策略,以及從海量大數據的離線計算到高并發在線服務的推薦引擎。
策略迭代
推薦系統的策略主要分為召回和排序兩類,召回負責生成推薦的候選集,排序負責將多個召回策略的結果進行個性化排序。下文會分別對召回和排序策略的迭代演進過程進行闡述。
召回策略迭代
我們從2015年底啟動了旅游推薦系統的建設,此時度假業務有獨立的周邊游頻道首頁,其中猜你喜歡展位的推薦策略由平臺統一負責,不能很好的解決旅游場景中的諸多問題。下文會按時間順序來闡述如何利用多種召回策略解決這些問題。
熱銷策略1.0
旅游推薦第一版的策略主要基于城市熱銷,不同于基于Deal所在城市統計分城市熱銷,這一版策略基于用戶常駐城市來統計,原因是不同城市的旅游資源分布各異,存在資源缺乏(客源地)、旅游資源豐富(供給地)以及本地人到周邊城市游玩的需求。即對于每個城市,都有其對應的“城市圈”Deal庫,比如:廊坊沒有滑雪場,但常駐城市為廊坊的用戶經常購買北京的滑雪場,因此當廊坊用戶在當地瀏覽周邊游頻道時會推薦出北京的滑雪場。
在具體實現時考慮旅游產品隨季節性變化的特性,銷量隨時間逐漸衰減,假定4周為1個變化周期,Deal得分公式為:deal_score = ∑((count(payorder) * α ^ i),其中count(payorder)指該Deal相應日期的支付訂單數,i指該日期距今的天數,取從1到28的整數,α為衰減系數(<1),Deal得分為一定周期內每日銷量得分的總和。
根據上述公式對每個城市都能統計Top N熱銷Deal,再根據Deal關聯POI過濾離當前瀏覽城市200km以外的Deal,比如:在瀏覽北京時推薦上海迪士尼門票不太好,不符合周邊游的定位。
這一階段還嘗試了熱門單、低價單、新單策略。新單和低價單比較好理解,就是給這些Deal一定的曝光機會。熱門單跟熱銷單類似,統計的是Deal瀏覽數據,熱門單召回的Deal跟熱銷策略差異不大。但由于推薦的評估指標是訪購率(支付UV/推薦UV),這些策略的效果不及熱銷,都沒有上線。
另外還初步嘗試了分時間上下文的推薦,比如:區分工作日/非工作日, 周一至周四過濾周末票、周五至周日過濾平日票,不過隨著推薦POI化而下線了。
這一階段的策略主要有兩個創新點:
- 基于用戶常駐城市統計熱銷,突破了Deal所在城市的限制,在本地能推薦出周邊城市的旅游產品。
- 通過銷量衰減,基本解決了季節性問題。
推薦POI化
每個景點下通常會有多個票種,每個票種下通常會有多個Deal,比如:故宮門票的票種有成人票、學生票和老人票,成人票下由于Deal供應商不同會有多個Deal,這些Deal的價格、購買限制可能會有所區別。如果按Deal樣式展示,可能故宮成人票、學生票都會被推薦出來,一方面大量重復相似Deal占據了推薦展位,另一方面Deal摘要信息較長,不利于用戶決策。因此2016年初啟動了推薦POI化,第一版的POI化方案基于Deal關聯的POI做推薦,即故宮成人票是熱銷單,實際推薦展示的故宮POI。 這個方案有兩個問題:
- 推薦的Deal有可能來自同一個POI,POI化需要去重。如果推薦展位有30個,候選推薦Deal的數量肯定要>=30,但也可能出現POI化后不足30個情況。
- 由Deal反推的POI銷量并不準確,POI實際銷量需要更精確的統計方法。
因此在2016年Q2上線了基于F值的POI熱銷策略,F值是美團點評內部的一種埋點追蹤方法,可以簡單理解為:用戶在瀏覽POI詳情頁時會在埋點日志的F值記錄POI ID,然后這個標記會一直帶到訂單中,這樣就能相對準確計算每個訂單的POI歸屬。
熱銷策略2.0
1.0版熱銷策略的主要問題是只考慮常駐城市的用戶在當地的購買偏好,簡而言之,只解決了上海人在瀏覽上海時的推薦問題,北京人在瀏覽上海時推薦的結果跟上海人推薦的一樣。放大看是本異地場景的問題,本異地場景的定義見下表。2.0版熱銷策略對本異地訂單分別統計,當某個用戶訪問美團時先判斷該用戶是本地還是異地用戶,再分別召回對應的POI,對于取不到常駐城市的用戶默認看做是本地請求。從推薦結果看北京本地人愛去歡樂谷,外地人到北京更愛去長城、故宮。
分類 | 場景 | 召回策略 |
---|---|---|
本地需求 | 瀏覽城市=常駐城市 (示例:北京人瀏覽北京) |
當地用戶購買的熱銷POI (POI所在城市不一定等于瀏覽城市) |
異地需求 | 瀏覽城市!=常駐城市 (示例:重慶人瀏覽北京) |
異地用戶購買的熱銷POI (所有非北京人購買的熱銷POI) |
這一版本中繼續嘗試了分時間上下文的細分推薦,統計一段時間內每天各小時的訂單分布,其中有3個鞍點,對應將一天分為早、中、晚3個時間段,分時間段統計POI熱銷。從召回層面看POI排序對比之前變化比較大,但由于下文中Rerank的作用,對推薦整體的影響并不大。
用戶歷史行為強相關策略
熱銷策略雖然能區分本異地用戶的差異,但對具體單個用戶缺少個性化推薦,因此引入用戶歷史行為強相關的推薦策略。取用戶最近一個月內瀏覽、收藏未購買的POI,按城市分組,按POI ID去重,越實時權重越高。
基于地理位置的推薦策略
上文的策略要么是有大量POI數據,要么是有用戶數據,如果用戶或POI沒有歷史行為數據或比較稀疏,上述策略就不能奏效,即所謂的“冷啟動”問題。在移動場景下通過設備能實時獲取到用戶的地理位置,然后根據地理位置做推薦。具體推薦策略分為兩類:
- 查找用戶實時位置幾公里范圍內的POI按近期銷量衰減排序,取Top POI列表。
- 查找用戶實時位置幾公里范圍內的用戶群,基于其近期發生的購買行為推薦Top POI。比如用戶定位在回龍觀,回龍觀附近沒有POI,但回龍觀的用戶會購買一些應季熱門POI。
地理位置推薦策略需要過濾用戶定位城市跟客戶端選擇城市不一致的情況,比如:定位北京的用戶在瀏覽上海時推薦北京周邊POI不太合適。
協同過濾策略
協同過濾是推薦系統中最經典的算法,相對于歷史行為強相關策略,對用戶興趣、POI屬性相當于是做了抽象和泛化。協同過濾算法主要分為ItemCF和UserCF兩類,我們首先實現了ItemCF,主要原因是:
- 性能:美團旅游POI數量遠小于用戶數,協同過濾算法核心的地方是需要維護一個相似度矩陣(Item/User相似度),維護POI相似度矩陣比維護用戶相似度矩陣代價小得多;
- 實時性:用戶有新行為,一定會導致推薦結果的實時變化;
- 冷啟動:新用戶只要對一個POI產生行為,就可以給他推薦和該POI相關的其他POI;
- 可解釋性:利用用戶的歷史行為給用戶做推薦解釋,可以令用戶比較信服。
基于POI瀏覽行為的協同過濾
根據UUID維度的瀏覽數據來計算POI之間的相似度,瀏覽行為比下單、支付行為更為稠密。時間窗口取一個月的數據,理論上只要計算計算能力不是瓶頸,時間窗口應該盡可能的長。相似度公式定義如下:
$$ w_{i,j}=\frac{|N(i)\bigcap N(j)|}{\sqrt{|N(i)||N(j)|}} $$
分母\( |N(i)| \)是瀏覽POI i的用戶數,分子\( |N(i)\bigcap N(j)| \)是一個月內同時瀏覽過POI i和j的用戶數。在計算完POI相似度后,再通過如下公式計算用戶u對POI j的興趣:
$$ p_{uj}=\sum_{i\in N(u)\bigcap S(j,K)}w_{ji}r_{ui} $$
這里\( N(u) \)是用戶瀏覽或購買過的POI的集合,\( S(j,K) \)是和POI j最相似的K個POI的集合,\( w_{ji} \)是POI j和i的相似度,\( r_{ui} \)是用戶u對POI i的興趣。協同過濾可以看做是用戶歷史行為強相關策略的泛化,最終的推薦結果示例:用戶瀏覽了“北京歡樂谷”,推薦出“北京海洋館”、“香山公園”。
用戶對POI的行為表每天離線生產好后更新,相當于只有當天之前的數據,缺少對用戶當天實時行為的反饋,因此增加基于用戶實時POI行為的協同過濾推薦,復用上文中的POI相似度計算結果。
基于用戶搜索行為的協同過濾
搜索行為是一種強意圖行為,旅游較多訂單來源于搜索入口,相當比例的搜索用戶沒有點擊任何POI,基于用戶搜索行為的推薦可以作為POI瀏覽推薦的一種補充。首先構造Query和POI的相似度矩陣,利用用戶搜索Query后10分鐘內瀏覽的POI構造 對,相似度算法跟POI相似度公式一致。
具體實現時以Query+City為Key,原因是旅游場景中存在部分全國連鎖POI,如:歡樂谷、方特,如果只以Query為Key,則跟“歡樂谷”Query最相關的POI可能是“北京歡樂谷”,那用戶在深圳搜索“歡樂谷”后會推薦出北京歡樂谷,不符合用戶需求。
相似度改進
上述相似度計算公式有兩個改進點:一是未考慮用戶行為的先后順序,比如用戶先后瀏覽了POI ,之前會兩兩計算相似度,實際只用計算A和 以及B和C的相似度即可,因為用戶是先瀏覽了A再瀏覽了B,所以瀏覽A時可以推薦B,但瀏覽B時推薦A不一定合適。二是未考慮POI之間的時間序列跨度,理論上A和B的相似度應該高于A和C的相似度。
改進后的相似度公式如下,其中\( l \)表示POI i和j的序列跨度長度,\( N_{ijl} \)是POI i和j序列長度為的次數,\( \alpha \)是序列跨度的衰減系數(<1):
$$ w_{ij}=\frac{\sum_{l}N_{ijl}*\alpha ^{l}}{\sqrt{|N(i)||N(j)|}}(i<j) $$
召回策略全景視圖
經過一年的迭代,目前線上在線的召回策略如下圖,此外還嘗試了基于ALS的矩陣分解,但推薦的結果比較冷門,可解釋性較差;另外啟動了基于用戶標簽的推薦,對用戶和POI都打上相應的屬性標簽,可以直接單維度標簽進行推薦,比如:給親子類用戶推薦親子類POI,也可以把標簽當做維度,多維度計算用戶和POI的相關性。
每類召回策略的結果都需要做過濾,過濾策略主要有幾類:
- 黑名單過濾。如源頭有臟數據或需要人工干預的Case。
- 無售賣POI過濾。即過濾沒有售賣Deal的POI。
- POI距離過濾。過濾據當前瀏覽城市幾百公里外的POI。
- 非當前城市過濾。過濾非當前瀏覽城市的POI。
- 已購買POI過濾。
其中前2類過濾策略對所有召回策略是通用的,都需要做,黑名單過濾考慮到數據更新的實時性,在線上處理,其他過濾策略可以在離線數據層統一處理。后3類只有特定召回策略需要,因為依賴用戶請求,只能在線上處理,具體規則如下:
召回策略 | 過濾規則 |
---|---|
熱銷策略 | POI距離過濾 |
歷史行為強相關 | 已購買POI過濾 非當前城市過濾 |
Location-Based | 非當前城市過濾 |
ItemCF | 已購買POI過濾 非當前城市過濾 |
排序策略迭代
每類召回策略都會召回一定的結果,這些結果去重后需要統一做排序。在早期只有熱銷策略一個時不需要Rerank,直接根據熱銷得分來排序,加入歷史行為強相關和Location-Based策略后也是按固定展位交叉展示的,比如:第1、3、5、7位給歷史行為強相關策略,第2、4、6、8位給Location-Based策略。
在2016年Q1初嘗試了第一版的Rerank策略,當時推薦樣式還是Deal,因此排序對象也是Deal,主要特征是30/180天的銷量/評分數據,因為考慮的特征比較少,上線后效果并不明顯。
在Q2初由于基本完成了POI化展示,排序對象變成POI,主要特征包括銷量、評分、價格、退款數據,上線后效果仍不明顯。
因為推薦列表頁跟篩選列表頁類似,在Q2中期嘗試直接接入篩選Rerank,但效果不太理想。隨后基于推薦的數據樣本重新進行了訓練,并新增了一些特征,特征上大致分為以下幾類:
特征維度 | 特征名稱 | 說明 |
---|---|---|
上下文 | HOUR_OF_DAY | 一天中的第幾小時 |
DAY_OF_WEEK | 一周中的第幾天 | |
CITY_ID | 客戶端選擇城市id | |
DISTANCE | 用戶和POI的距離 | |
POI | REC_POI_CTR_DAY7 ... |
POI 7天的點擊率 |
POI_ALLCATE_PAY_F_CNT_DAY7 ... |
POI 7天的支付數據 |
|
POI_COMMENT_CNT_DAY7 ... |
POI 7天的評分數 |
從上表看在銷量和評價基礎上主要新增了上下文特征、距離特征和訪購相關特征,注意到HOUR_OF_DAY、DAY_OF_WEEK、CITY_ID并沒有采用one-hot編碼,在線上實驗one-hot編碼效果并不優于直接使用原始值。可能的解釋是HOUR_OF_DAY離散值可以用于樹模型來分類,比如:0~11點可以表示上午、12點~18點可以表示下午、19點~23點表示夜晚;同理DAY_OF_WEEK周一到周四可以認為是平日,周五到周日認為是周末;CITY_ID可能的解釋是ID越小,越是開站較早的城市,也是更熱門的城市。
模型上取最后一個點擊前的樣本為候選樣本集,以支付為正樣本,其他為負樣本,正負樣本采樣比為1:10。如果不做樣本采樣,假設每100人訪問只有1個支付,每次訪問列表頁假設用戶平均能看到10個POI,即正負樣本比例大約為1:1000,樣本分布極不均衡,容易導致過擬合。模型訓練上采用XGBoost算法,上線后點擊率和訪購率均明顯正向,證明了Rerank的有效性。
在上述基礎上后續又逐步豐富了上下文特征,比如:召回可能觸發周邊城市圈的POI,因此增加POI是否本城市的特征,另外熱銷召回策略拆分了本異地,Rerank也對應增加了用戶請求是否本異地特征;增加了User-POI組合特征:User 7天內是否瀏覽/收藏過POI、實時特征、基于協同過濾的User-POI相關性等,跟歷史行為強相關、協同過濾的召回策略能相呼應;增加了POI靜態屬性特征,如:星級,另外把POI的銷量也按本異地進行了拆分。這些特征上線后效果基本都正向,符合預期。
特征維度 | 特征名稱 | 說明 |
---|---|---|
上下文 | SCENE_LR IS_POI_LOCAL |
是本地OR異地用戶 POI是否本城市 |
User-POI | POI_VIEWED_DAY7 ... |
POI 7天內是否被瀏覽過 |
POI_RT_VIEWED ... |
實時特征:用戶最近是否瀏覽過 | |
REC_POI_CF_SCORE ... |
通過POI CF計算出的User和POI的語義相關性 | |
POI | PLACE_STAR ... |
景區星級 |
POI_SCENE_PAY_F_CNT_DAY7 ... |
POI分本異地的銷量 (當用戶是本地請求時使用本地銷量, 異地時使用異地銷量) |
模型上嘗試了短周期模型+長周期模型的融合,短周期為近期一個月數據,長周期為近期三個月數據。從線上結果看直接用短周期模型效果最好,這可能跟旅游應季變化快有關。除了上述特征外,后續還可以增加User個性化特征、天氣上下文特征、POI特征CTR/CVR可以拆分本異地等。
排序策略全景視圖
推薦的離線訓練流程跟搜索、篩選排序保持一致,流程圖如下:
- 首先是數據標注,數據源是原始的樣本日志,記錄在Hive中,輸出是ISample對象,同時打上label。另外可能部分特征需要在線上生產并寫入樣本日志中,比如:實時特征,沒辦法用離線ETL采集;
- 樣本選擇:對初始樣本做過濾,比如:過濾最后一個點擊樣本之后的數據,輸出還是ISample;
- 特征抽取:在樣本中有POI ID,根據POI ID可以抽取POI的銷量、評價等特征;同理可以根據樣本中的UUID抽取用戶相關特征。這樣就生成了帶上Feature的Sample;
- 數據采樣:按事先定義的正負樣本比例對樣本進行抽象;
- 訓練集構建&輸出:按XGBoost格式輸出訓練集。
整個訓練集的構造過程由Scala編寫在Spark集群上運行,而由于XGBoost的Spark版本效果不太穩定,在最后的模型訓練與評估中使用的XGBoost的單機版本,模型的訓練參數(迭代次數、樹的深度等)一般選取經驗值,訓練集選一個月的數據,測試集一般選訓練集日期后的若干天,離線評估指標主要參考AUC,離線效果有提升就會上線ABTest實驗,逐步迭代。
工程架構設計
推薦系統的整體工程架構如下圖,從下至上包括離線計算層、核心數據層、推薦服務層和應用場景層,另外是后臺配置管理系統和數據調度服務。
離線計算層
離線計算層除了Rerank需要的特征和訓練日志外,主要包括基礎數據和應用數據兩類。基礎數據中最重要的是Deal和POI的數據,為了保證數據的準確性和實時性,Deal和POI的數據直接從旅游產品中心去取,通過定時全量拉取并輔以消息隊列實時更新。應用數據按生產方式又可以分為三類:
- Hive ETL生產的數據:比如POI過濾需要用到的離線表(主門店等邏輯),另一大類是統計數據,比如:城市POI熱銷、線路游熱銷、用戶對POI的瀏覽/購買行為。
- Spark生產的數據:比如:User CF、POI CF、矩陣分解算法等,這類數據生產邏輯復雜,不好直接通過ETL計算完成。
- Storm生產的數據:用戶實時行為在召回、排序都需要用到,目前公司提供統一的實時用戶行為數據流user__action_basic,包括:瀏覽/收藏 POI/Deal、下單、支付、消費、退款,從中過濾出旅游POI/Deal的行為即可。
核心數據層
抽象出核心數據層的一個重要原因是需要離線計算工程和線上服務工程復用DataSet,從供線上使用的存儲方式看可以分為三類:
- 存儲在ElasticSearch(以下簡稱ES)中的數據。主要是POI/Deal索引,比如:POI的地理位置、所在城市,當線上需要根據地理位置過濾時可使用ES查詢,比如:城市圈的距離限制,Location-Based策略一定距離內的召回。另外對于多維查詢場景ES也比KV存儲更為合適。這類數據通過公司統一的任務調度系統來定時調度,通常幾小時更新一次。這里為ES索引建立一個別名,離線更新索引切別名的指向,保證操作的原子性。
- 存儲在DataHub中的數據。DataHub是酒旅搜索團隊開發的一套數據管理系統,集數據存儲、管理、使用于一體。目前支持將Hive表的數據定期導入,DataHub內部主要使用Tair作為存儲,對客戶端使用透明,客戶端接口支持一維和二維的Key,接口對應用方基本是一致的,另外應用方也不需要自行維護Tair集群配置管理了。DataHub自帶調度功能,通過掃描HDFS分區生成后自動寫入Tair。
- 直接存儲在Tair中的數據。主要面向DataHub還不支持的兩類場景,一是實時數據的存儲落地,二是value直接存儲對象,存儲為對象的好處是從Tair讀取出來的對象可直接供線上使用,無需自行序列化和賦值。實時數據無需定時調度,通過Spark直接寫入Tair的數據通常需要依賴上游Hive表先Ready才能執行,所以通過公司統一的數據協同平臺調度。
推薦服務層
服務上下游
推薦上下游的架構圖如下圖,客戶端向API發起調用,API調用推薦服務拿到推薦的ID再添加供App展示用的相關字段傳會給App。推薦和搜索沒有整合成一個服務的重要原因是推薦的召回策略復雜多樣,每次請求可能命中多個召回策略,而搜索單次請求的意圖一般比較單一,通常只有一個召回策略。另外推薦服務重點在召回和過濾,Rerank調用獨立的rank服務,原因是推薦Rerank和搜索篩選Rerank在特征上有很多是可以復用的,比如:用戶特征、POI特征等。
整體流程
推薦服務向下從數十個數據源中獲取數據,經過業務邏輯處理后向上支持數十個應用場景,整個調用流程如下:
- RecommendServicePublisher作為服務的入口,從Client接到Request請求后首先驗證請求是否合法,比如:請求參數中場景Booth和UUID不能為空。
- 構造請求上下文Context,其中會生成唯一的global ID標識一次請求,根據UUID查詢用戶畫像服務獲取常駐城市,根據定位的經緯度查詢定位城市,以及根據ABTest分流配置獲取處理請求的召回排序Strategy。
- 根據請求場景的Booth獲取對應的Handler,默認使用統一的AbstractHandler即可,包括召回、過濾、rerank、post rerank。
- 對Handler返回的結果做包裝,增加召回和排序策略名稱、得分等,最終返回給Client。
核心流程與模型
Handler是整個流程的核心,其調用流程如下:
- Handler根據不同的Strategy獲取對應的SelectRule集合,一個場景Booth可能對應多個Strategy,跟ABTest對應,比如:Baseline就是一個Strategy。每個Strategy可能有多個SelectRule,比如:Baseline策略由歷史行為強相關SelectRule、Location-Based SelectRule、熱銷Rule等組成。
- 召回:每個SelectRule又對應多個Selector,多個Selector通過線程池并發獲取結果,比如:Location-Based Rule可以細分為基于周邊熱銷POI召回和基于周邊用戶購買POI召回。Selector可再做抽象,比如:分本異地場景的城市熱銷策略,美團和點評雙平臺都需要,只是數據源稍有不同,另外對于從ES和DataHub獲取的數據可以加Cache。
- Merge去重:多個召回策略的結果需要Merge去重,比如早期沒有Rerank時Location-Based策略固定在2、4、6位。
- 過濾:具體有兩級過濾,一級是針對SelectRule的,比如:針對歷史行為強相關策略中基于瀏覽行為和收藏行為召回的結果都需要過濾用戶已購買過的POI;另一級是針對所有策略通過的過濾,比如黑名單、旅行社代理商。
- 重排序:對于POI列表調用POI Rerank服務,對于Deal列表調用Deal Rerank服務。
- PostRerank:一般用于處理廣告運營的需求和人工干預的Case。
核心的對象模型如下圖:
監控降級
監控分為離線監控和實時監控兩部分,離線監控使用Falcon來監控以下幾類指標:
- JVM監控:比如FullGC次數、內存使用情況、Thread block情況
- ES監控:ES查詢次數和平均響應時間
- 業務監控:各接口、各策略的請求次數和平均響應時間
實時監控接入公司統一的實時數據統計平臺,可以分時、分多粒度統計各Booth的請求次數和響應時間。
降級主要通過Hystrix來實現,比如:調用Rerank服務在一定時間內響應時間超過設定的閾值,則直接熔斷不請求Rerank服務。
工具化
推薦服務開發了Debug工具,輸入支持城市、展位、UUID、經緯度等參數,輸出展示了POI/Deal的頭圖、標題、和用戶的距離、召回排序策略與得分等。方便PM和RD測試、定位追查Case。
應用場景
推薦系統支持了美團/點評共20個應用場景,主要場景是周邊游頻道首頁猜你喜歡,其召回策略在上文中已有闡述,這里重點闡述其他幾類推薦場景:
跟團游推薦
跟團游Deal一般會綁定多個景點,不適合按POI樣式展現,因此采用Deal形式展現,召回策略跟熱銷POI策略類似,區分本異地,從結果看北京本地人會推薦“古北水鎮一日游”,外地人瀏覽北京時會推薦“故宮、長城一日游”。
篩選異地召回
用戶在篩選酒店時會先選擇入住城市再篩選該城市的酒店POI,而周邊游存在客源地旅游資源不豐富的問題,篩選時需要突破選擇城市限制,能夠推薦出周邊城市的熱門POI,篩選異地召回上線后增加了一定比例的訂單,是對本地召回的有效補充。
篩選主題標簽挖掘
即為POI打標簽,用戶可以用這些標簽進行篩選,比如:附近熱門、近郊周邊、周末去哪、親子同樂、夜場休閑。每個標簽都可以定義一套挖掘方法,比如:“親子同樂”有以下幾類方法:
- POI下有親子票種
- Deal標題包含“親子”
- 同一POI下同時包含“成人票”和“兒童票”
- 用戶畫像為“親子”的用戶最近一個月購買的POI
上述挖掘方法偏規則,后續希望能通過半/無監督方法,挖掘POI描述和評論,自動為POI打標。
搜索少/無結果推薦
搜索少結果推薦是指當搜索結果POI類聚結果數=1時,為豐富頁面內容給用戶提供推薦信息。這里重點利用搜索的POI結果根據POI CF觸發推薦,以及利用搜索POI的品類進行同城市同品類推薦。
搜索無結果推薦可以直接統計搜索Query后一定時間內用戶瀏覽的POI做推薦,但這個策略的覆蓋面有限,進一步可以計算一段時間內的Query CF,然后做協同推薦;另一方面可以通過意圖識別判斷Query中是否有品類詞,觸發同品類推薦。
酒旅交叉推薦
目前只實現了酒店和旅游之間的交叉推薦,當用戶在酒店頻道搜索時先判斷Query是否旅游意圖,其中重點分析兩類意圖:一是景點POI意圖,推薦該景點幾公里范圍內的POI;二是品類意圖,比如:溫泉、滑雪,會推薦用戶定位附近該品類的熱銷POI。
在酒店POI詳情頁會獲取酒店POI的地理位置,推薦酒店附近的景點。對于異地用戶瀏覽酒店時都會觸發景點推薦,對于本地用戶只有在瀏覽郊區酒店時會觸發旅游推薦,這是假設本地用戶在瀏覽市區酒店時旅游度假的意圖可能不明顯。
除了在各類推薦場景的應用,這些策略在運營上也有應用嘗試,比如:用戶瀏覽或購買過POI后根據POI CF給用戶PUSH相似的POI,實驗證明推薦策略的PUSH點擊率要高于平均水平。
未來的挑戰
經過一年多的迭代優化,周邊游頻道內相當比例的訂單來自推薦,線上支持了20個左右的推薦場景,很多推薦策略被作為特征加入搜索、篩選Rerank,有明顯正向效果,在用戶運營上也有了初步的探索。基于目前的推薦系統本身還有不少優化點:
- 召回策略:策略的廣度和深度都有不少提升空間,廣度方面可以繼續探索矩陣分解FFM、User CF、基于用戶畫像的推薦、圖挖掘;深度方面嘗試LLR等多種相似度計算方法、以及多時間/多用戶維度改進召回策略。數據上可以擴大到酒店甚至美團全平臺的用戶數據,另外對策略的離線實現還要更模塊化、抽象化,比如:相似度改進算法在一處場景驗證有效,可快速推廣上線到其他場景
- 排序策略:特征工程方面可以增加User個性化特征、天氣/Listwise上下文特征等,模型上可以嘗試DNN等方法,評估指標可以從訪購率改進成訪消率(消費UV/訪問UV),另外對美團/點評雙平臺可以定制不同的特征數據和排序策略
- 工程架構:搜索少/無結果推薦從搜索工程遷移到推薦工程,另外對核心數據層存儲方式的邊界劃分,線上服務層的緩存、Selector/Rerank降級、Filter/Merge邏輯梳理等需要做“輕量重構”
- 應用場景:除了在酒店購買前的交叉推薦外還可以增加購買后的推薦,以及和機票、火車票大交通相關的交叉推薦,在旅游內部可以探索更多的場景化建設,比如:親子游、情侶游
跳出目前單一的以POI/Deal列表為主體的推薦形態看,可以從用戶、場景、內容、觸達方式四個方面看如何做好旅游推薦:
用戶需求
首先考慮用戶是誰?要滿足用戶的什么需求?這里可以利用美團/點評的數億用戶,打“人群標簽”,是一二線城市高端品質女用戶、勤儉住宿的中年大叔還是三線城市實惠型年輕媽媽。然后分析這些人群背后的需求,是本地休閑用戶、差旅用戶還是高頻度假用戶,不同用戶的需求是不一樣的。
場景劃分
當知道用戶后需要知道用戶的場景是什么?可以從四個維度定義場景:時間、位置、行為、渠道。
時間很好理解,當用戶在周四周五搜索“滑雪場”,會被認為是休閑度假周末用戶,可以協同推薦北京郊區的滑雪場。
地理位置是核心要素,要根據用戶的常駐城市和客戶端選擇城市來判斷是本地還是異地需求,對于異地的差旅用戶可以推薦商務型的酒店。
行為是用戶需求最直接的反應,比如:用戶搜索“古北水鎮”,不管用戶后續是否有瀏覽行為,都可以推薦古北水鎮相關的酒店和景點門票。
渠道包括美團/點評雙平臺App、i版、PC等多個終端,以美團App為例,周邊游、酒店、機票/火車票頻道的用戶特征都不一樣,比如:大交通頻道最常見的是差旅用戶、周邊游頻道更多是本地度假休閑的人群。
內容形態
知道了用戶是誰以及處于什么場景,要考慮提供什么樣的內容產品?對于美團來說核心是交易,內容不是最核心的目標,但內容是一個非常好的引流措施。以本地場景為例,可以加強場景建設,比如:親子、團建、溫泉等;異地行前場景可以加強目的地、點評游記攻略、酒店交通行程安排等內容建設。
觸達方式
除了目前的搜索推薦外,還可以增加定向投放、內容引導、廣告植入、活動運營等多種觸達方式。
總之旅游推薦問題復雜多樣,需要從度假出行六要素:吃、住、行、游、購、娛綜合考慮和規劃,對產品形態、業務策略、技術架構都還有很大的挑戰和機遇。
來自:http://tech.meituan.com/travel-recsys.html