1. 程式人生 > >58同城智慧推薦系統的演進與實踐

58同城智慧推薦系統的演進與實踐

58同城作為中國最大的分類資訊網站,向用戶提供找房子、找工作、二手車和黃頁等多種生活資訊。在這樣的場景下,推薦系統能夠幫助使用者發現對自己有價值的資訊,提升使用者體驗,本文將介紹58同城智慧推薦系統的技術演進和實踐。

58同城智慧推薦系統大約誕生於2014年(C++實現),該套系統先後經歷了招聘、房產、二手車、黃頁和二手物品等產品線的推薦業務迭代,但該系統耦合性高,難以適應推薦策略的快速迭代。58同城APP猜你喜歡推薦和推送專案在2016年快速迭代,產出了一套基於微服務架構的推薦系統(Java實現),該系統穩定、高效能且耦合性低,支援推薦策略的快速迭代,大大提高了推薦業務的迭代效率。此後,我們對舊的推薦系統進行了重構,將所有業務接入至新的推薦系統,最終成功打造了統一的58同城智慧推薦系統。下面我們將對58同城智慧推薦系統展開介紹,首先會概覽整體架構,然後從演算法、系統和資料三方面做詳細介紹。

整體架構

  首先看一下58同城推薦系統整體架構,一共分資料層、策略層和應用層三層,基於58平臺產生的各類業務資料和使用者積累的豐富的行為資料,我們採用各類策略對資料進行挖掘分析,最終將結果應用於各類推薦場景。

                        

  • 資料層:主要包括業務資料和使用者行為日誌資料。業務資料主要包含使用者資料和帖子資料,使用者資料即58平臺上註冊使用者的基礎資料,這裡包括C端使用者和企業使用者的資訊,帖子資料即使用者在58平臺上釋出的帖子的基礎屬性資料。這裡的帖子是指使用者釋出的房源、車源、職位、黃頁等資訊,為方便表達,後文將這些資訊統稱為帖子。使用者行為日誌資料來源於在前端和後臺的埋點,例如使用者在APP上的篩選、點選、收藏、打電話、微聊等各類操作日誌。這些資料都存在兩種儲存方式,一種是批量儲存在HDFS上以用作離線分析,一種是實時流向Kafka以用作實時計算。

  • 策略層:基於離線和實時資料,首先會開展各類基礎資料計算,例如使用者畫像、帖子畫像和各類資料分析,在這些基礎資料之上便是推薦系統中最重要的兩個環節:召回和排序。召回環節包括多種召回源的計算,例如熱門召回、使用者興趣召回、關聯規則、協同過濾、矩陣分解和DNN等。我們採用機器學習模型來做推薦排序,先後迭代了LR、FM、GBDT、融合模型以及DNN,基於這些基礎機器學習模型,我們開展了點選率、轉化率和停留時長多指標的排序。這一層的資料處理使用了多種計算工具,例如使用MapReduce和Hive做離線計算,使用Kylin做多維資料分析,使用Spark、DMLC做大規模分散式機器學習模型訓練,使用theano和tensorflow做深度模型訓練。

  • 再往上就是應用層,我們通過對外提供rpc和http介面來實現推薦業務的接入。58同城的推薦應用大多是向用戶展示一個推薦結果列表,屬於topN推薦模式,這裡介紹下58同城的幾個重要的推薦產品:

    • 猜你喜歡:58同城最重要的推薦產品,推薦場景包括APP首頁和不同品類的大類頁,目標是讓使用者開啟APP或進入大類頁時可以快速找到他們想要的帖子資訊,這主要根據使用者的個人偏好進行推薦。

    • 詳情頁相關推薦:使用者進入帖子詳情頁,會向用戶推薦與當前帖子相關的帖子。該場景下使用者意圖較明顯,會採用以當前帖子資訊為主使用者偏好資訊為輔的方式進行推薦。

    • 搜尋少無結果推薦:使用者會通過品類列表頁上的篩選項或搜尋框進入品類列表頁獲取資訊,若當前篩選項或搜尋條件搜尋出的結果較少或者沒有結果,便會觸發推薦邏輯進行資訊推薦。此時會結合當前搜尋條件的擴充套件以及使用者偏好資訊進行推薦。

    • 個性化推送(Push):在使用者開啟APP前,將使用者感興趣的資訊推送給他們,促使使用者點選,提高使用者活躍度。這裡包含推送通知的生成和推送落地頁上帖子列表的生成兩個推薦邏輯。值得一提的是推送是強制性的推薦,會對使用者形成騷擾,因此如何降低使用者騷擾並給使用者推薦真正感興趣的資訊尤為重要。

    • Feed流推薦:我們的推薦產品在某些推薦場景下是以Feed流的形式展現的,例如APP訊息中心的今日推薦場景、推送落地頁場景。使用者可以在這些頁面中不斷下拉重新整理消費資訊,類似時下火熱的各大資訊Feed流推薦。

推薦系統是一個複雜的工程,涉及演算法策略、工程架構和效果資料評估三方面的技術,後文將分別從這三方面介紹58同城推薦系統。

演算法

推薦涉及前端頁面到後臺演算法策略間的各個流程,我們將推薦流程抽象成如下圖所示的召回、排序、規則和展示四個主要環節:

                    

  • 召回環節即使用各種演算法邏輯從海量的帖子中篩選出使用者感興趣的帖子候選集合,一般集合大小是幾十到上百。

  • 排序即對候選集合中的帖子進行打分排序,這裡一般會使用機器學習排序模型,排序環節會生成一個排序列表。

  • 規則環節即我們可能對排序列表採取一定的規則策略,最終生成一個包含N條結果的列表。例如在規則環節我們可能會採取不同的去重策略,如文字去重、圖片去重、混合去重等,可能會採取不同的列表打散策略,可能會迭代產品經理提出的各種規則邏輯。由於推薦系統的最終評價是看統計效果,因此各種人為的規則都會影響最終結果,我們抽象出規則環節後便可以對任何邏輯做線上ABTest,最終評價相關邏輯是否合理。

  • 生成N條推薦結果列表後,不同的前端展示方式也會影響最終的推薦效果,例如不同的UI設計,採用大圖模式還是小圖模式,頁面上展示哪些欄位都會影響使用者在推薦列表頁上的點選,因此在推薦產品迭代過程中不同的展示樣式迭代也很重要。

在上述的四個環節中,召回和排序是推薦系統最重要的兩個環節。規則和展示樣式一般變化週期較長,而召回和排序有很大的挖掘空間,會被不斷的迭代,我們的推薦演算法工作也主要是圍繞召回和排序進行。下圖是我們推薦演算法的整體框架,主要包括基礎資料的計算以及上層的召回策略和排序模型的迭代。

                   

基礎資料計算主要包括使用者標籤和帖子標籤的挖掘,這部分工作由使用者畫像、搜尋和推薦多個團隊共同完成,最終各團隊共享資料。基於使用者註冊時填寫的基礎屬性資訊和使用者行為日誌,可以挖掘出使用者人口屬性和興趣偏好資訊,如使用者的年齡、性別、學歷、收入等基礎屬性,使用者感興趣的地域商圈、二手房均價、廳室、裝修程度等偏好資訊。帖子標籤挖掘包括提取帖子的固定屬性、挖掘衍生屬性以及計算動態屬性。固定屬性直接從帖子資料庫提取即可,如分類、地域、標題、正文、圖片、房源價格、廳室、小區等。我們還會基於貼子資訊是否完備、價格是否合理、圖片質量好壞、發帖人質量等多個維度來計算帖子質量分。基於使用者行為日誌資料可以計算帖子的PV、UV、點選率、轉化率、停留時長等動態屬性。這些資料最終會在召回環節和排序環節使用,例如基於使用者標籤和帖子標籤可以進行興趣召回,將使用者標籤和帖子標籤作為特徵迭代機器學習模型。

       召回主要負責生成推薦的候選集,我們採用多種召回源融合的方式來完成該過程。我們先後迭代瞭如下各類召回策略:

  • 熱門召回。基於曝光和點選日誌,我們會計算不同粒度的熱門資料。以二手車業務線為例,從粗粒度到細粒度的資料包括:城市下的熱門商圈、商圈下的熱門車系和品牌、特定車系和品牌下的熱門車源等。每一個車源的熱度我們通過最近一段時間內帖子的PV、UV、CTR等指標來衡量,這裡的CTR會通過貝葉斯和COEC做平滑處理。熱門召回策略會在冷啟動時被大量採用。

  • 地域召回。58同城是向用戶提供本地生活服務類資訊,使用者的每次訪問都會帶上地域資訊,如選擇的城市、定位的地點等。我們主要結合地域資訊和熱門資料做召回,如附近最新或最熱帖子召回、城市熱門帖子召回等。

  • 興趣召回。基於帖子基礎屬性欄位和帖子標籤資訊,我們構建了一套帖子檢索系統,通過該系統能夠以標籤或屬性欄位檢索出最新發布的帖子。在使用者畫像中,我們計算了每個使用者的興趣標籤,因此基於使用者興趣標籤便能在檢索系統中檢索出一批帖子,這可以作為一種召回源。此外,在帖子詳情頁相關推薦場景中,我們也可以利用當前帖子的屬性和標籤資訊去檢索系統中檢索出相關帖子作為召回資料來源。這兩種檢索召回其實就是我們常說的基於內容的推薦。

  • 關聯規則。這裡並非直接採用傳統Apriori、FP-growth關聯規則演算法,而是參考關聯規則思想,將最近一段時間中每個使用者點選所有物品當做一次事務,由此計算兩兩物品之間的支援度,並在支援度中融入時間衰減因子,最終可以得到每個物品的topK個關聯性強的物品。這種召回方式其實類似協同過濾中的item相似度矩陣計算,我們主要將其應用在詳情頁相關推薦中。

  • 協同過濾。我們使用Spark實現了基於User和基於Item的批量協同過濾計算,由於資料量大,批量計算會較消耗時間,我們又實現了基於Item的實時協同過濾演算法。通常情況下我們會直接將使用者的推薦結果列表作為一種召回源,而在詳情頁相關推薦場景,我們還會使用協同過濾計算出的Item相似度矩陣,將帖子最相似的topK個帖子也作為一種召回源。

  • 矩陣分解。我們引入了SVD演算法,將使用者對帖子的點選、收藏、分享、微聊和電話等行為操作看作使用者對帖子進行不同檔次的評分,從而構建評分矩陣資料集來做推薦。

  • DNN召回。Google在YouTube視訊推薦上使用了DNN來做召回,我們也正在進行相關嘗試,通過DNN來學習使用者向量和帖子向量,並計算使用者最相近的topK個帖子做為召回源。

上述不同的召回演算法都產生出了一部分推薦候選資料,我們需要將不同的召回資料融合起來以提高候選集的多樣性和覆蓋率,這裡我們主要使用兩種召回融合策略:

  • 分級融合。設定一個候選集目標數量值,然後按照效果好壞的次序選擇候選物品,直至滿足候選集大小。假設召回演算法效果好壞的順序是A、B、C、D,則優先從A中取資料,不足候選集目標數量時則從B中取資料,依次類推。我們的系統支援分級融合策略的配置化,不同召回演算法的先後順序可以靈活配置。這裡的效果好壞順序是根據離線評價和線上評價來決定的,例如離線我們會比較不同召回演算法的召回率和準確率,線上我們會比較最終點選或轉化資料中不同召回演算法的覆蓋率。

  • 調製融合。按照不同的比例分別從不同召回演算法中取資料,然後疊加產生最終總的候選集。我們的系統也支援調製融合策略的配置化,選擇哪些召回演算法、每種召回演算法的選擇比例均可以靈活配置。這裡的比例主要根據最終線上點選或轉化資料中不同召回演算法的覆蓋率來設定。

召回環節新召回源的新增或者新融合策略的上線,例如開發了一種新召回演算法、需要修改調製融合策略中的配比等,我們都會做線上ABTest,最終通過比較不同策略的效果來指導我們的迭代。值得一提的是,召回環節我們還會有一些過濾規則,例如過濾低質量帖子、在某些特定場景下對召回演算法產生的結果加一些條件限制等。

排序環節我們主要採用Pointwise方法,為每個帖子打分並進行排序,通過使用機器學習模型預估帖子的點選率、轉化率和停留時長等多指標來做排序。早期我們主要優化點選率,目前我們不僅關注點選率外還會注重轉化率的提高。在58同城的產品場景中,轉化主要指使用者在帖子詳情頁上的微聊、打電話操作。

排序離線流程主要包括樣本生成和選擇、特徵抽取、模型訓練和評價。首先對埋點日誌中的曝光、點選、轉化和停留時長等資料做抽取解析,如基於曝光序列號關聯各類操作、解析埋點引數(例如日誌中記錄的實時特徵)、解析上下文特徵等,並同時打上label,生成模型樣本。然後對樣本進行過濾,例如過濾惡意使用者樣本、過濾無效曝光樣本等。然後對樣本做特徵抽取,生成帶特徵的樣本,我們主要從使用者、帖子、發帖人和上下文四個維度做特徵工程。之後,按照一定正負樣本比例做取樣,最終進行模型訓練和評估,離線評估指標主要參考AUC,離線效果有提升後會進行ABTest上線,逐步迭代。我們先後迭代上線瞭如下排序策略:

  • 規則序。早期未上線機器學習模型時,對候選集中的帖子會直接使用重新整理時間、統計CTR或者一些產品規則來做排序。

  • 單機器學習模型。我們最早實踐的是LR模型,它是線性模型,簡單高效、可解釋性好,但對特徵工程要求較高,需要我們自己做特徵組合來增強模型的非線性表達能力,早期我們使用LibLinear來訓練模型,後來遷移到了Spark上。之後我們引入了XGBoost樹模型,它非線性表達能力強、高效穩定,是目前開源社群裡最火熱的模型之一,最初我們採用單機版本訓練,後期將XGBoost部署在我們的yarn叢集上,使用分散式版本進行訓練。同時,我們應用了FM模型,相比於LR模型它引進了特徵組合,能夠解決大規模稀疏資料下的特徵組合問題,我們主要使用分散式FM (DiFacto,FM on Yarn)來進行模型訓練。上述這些模型都是批量更新,通常是一天更新一次,為了快速捕捉使用者行為的變化,我們還引入Online Learning模型,主要嘗試應用FTRL方式去更新LR模型,在某些場景下獲得了穩定的效果提升。

  • 融合模型。類似Facebook、Kaggle的做法,我們實踐了GBDT+LR和GBDT+FM的模型融合方案。首先利用XGBoost對原始特徵做處理生成高階特徵,然後輸入到LR和FM模型中,目前我們的點選率預估模型中效果最佳的是GBDT+LR融合模型,轉化率預估模型中效果最佳的是GBDT+FM融合模型。此外,我們還會嘗試將某個單指標(如點選率)下多個模型的預測結果進行融合(如相加或相乘等),也會將多個指標(點選率、轉化率和停留時長)的模型進行融合(如相乘)以觀察效果。

  • 深度模型。深度學習正逐漸被各大公司應用於推薦系統中,我們也正在進行嘗試。目前,我們已將FNN(Factorisation machine supported neuralnetwork)模型應用在我們的推薦排序中,相比單機器學習模型,FNN有較穩定的效果提升,但比融合模型效果要稍差,目前我們正在進行深度模型的調優,並在嘗試引入Wide&Deep等其他深度模型。

基於上述基礎機器學習工具,目前我們主要會迭代點選率、轉化率和停留時長預估模型,線上會ABTest上線單指標模型、多指標融合模型,以提高推薦效果。

架構

對於推薦系統來說,一套支撐演算法策略高效迭代的推薦後臺系統至關重要,我們基於微服務架構設計了推薦後臺系統,它擴充套件性好、效能高,系統架構如下圖所示,系統分為資料層、邏輯層和接入層,資料層提供各類基礎資料的讀取,邏輯層實現召回和排序策略並支援不同策略的ABTest,接入層對外提供了通用的訪問介面。

                    

資料層提供推薦邏輯所需要的各類資料,這些資料儲存在WRedis、檔案、WTable等多種裝置上,我們將所有資料的讀取都封裝成RPC服務,遮蔽了底層的儲存細節。這裡包括檢索服務、召回源讀取服務、帖子特徵中心和使用者特徵中心:

  • 檢索服務。我們搭建了一套搜尋引擎用做召回檢索,支援基於各類搜尋條件去檢索資料,例如可以檢索出價格在200萬至300萬之間的回龍觀兩室的房源、檢索出中關村附近的最新房源。該服務主要應用於這幾類場景:在猜你喜歡推薦場景中基於使用者標籤去檢索帖子、在相關推薦場景中基於當前帖子屬性去檢索相關帖子、冷啟動時基於地域資訊召回附近的帖子等。

  • 召回源讀取服務。提供各類召回源資料的讀取,這些召回源資料通過離線或實時計算得到,包括熱門資料、協同過濾資料、關聯規則資料、矩陣分解結果等。該服務設計得較靈活,支援任意召回源的增加。

  • 帖子特徵中心。提供帖子所有屬性欄位的讀取,在召回、排序和推薦主體邏輯中會使用到這些帖子屬性,一般情況我們會在召回環節讀取出所有帖子屬性,然後應用於排序和規則邏輯中。召回得到的候選集大小一般是幾十到幾百,為了支援高效能的批量讀取,我們選擇使用WRedis叢集儲存帖子屬性,並通過多執行緒併發讀取、快取、JVM調優等多項技術保證服務效能。目前,該服務每天承接數億級請求,平均每次讀取150條資料,耗時保證在2ms之內。

  • 使用者特徵中心。UserProfile資料包括使用者離線/實時興趣標籤、人口屬性等,該資料會在召回環節使用,例如使用使用者興趣標籤去檢索帖子作為一種召回源,也會在排序環節使用,例如將使用者標籤作為機器學習排序模型的特徵。

邏輯層實現了詳細的推薦策略,包括推薦主體服務、召回服務、排序服務和ABTest實驗中心。這些服務由不同的開發人員維護,保證了推薦策略的高效迭代,例如召回和排序是我們經常迭代的環節,由不同的演算法人員來完成,召回服務和排序服務的分離降低了耦合,提高了迭代效率。

  • 推薦主體服務。接收推薦請求,解析推薦場景引數,呼叫使用者特徵中心獲取使用者資訊,請求ABTest實驗中心獲取對應場景的ABTest實驗引數,如召回策略號、排序演算法號、規則號和展示號。然後將推薦場景引數、ABTest實驗引數等傳送至召回服務獲得候選集列表,之後再呼叫排序服務對候選集進行排序,最終對排序列表做相關規則處理,將結果列表封裝返回。

  • 召回服務。接收場景引數和召回策略號引數,呼叫檢索服務和召回源讀取服務讀取各類召回資料,並進行分級融合或調製融合。我們實現了召回策略的配置化,一個召回號對應一種召回策略,策略採用哪種融合方式、每種融合方式下包含哪些召回源、不同召回源的數量均通過配置來完成。我們將召回配置進行Web化,演算法或產品人員只需在Web頁面上配置即可生效策略。此外,召回層還包括一些過濾規則,例如過濾低質量資訊、過濾使用者歷史瀏覽記錄、過濾產品指定的符合某些特定條件的資料等。

  • 排序服務。接收場景引數、使用者資訊、候選集列表和排序演算法號等引數,呼叫機器學習排序模組,對候選集列表做排序。我們設計了一套通用的特徵提取框架,保證機器學習離線模型訓練和線上排序共用相同的特徵提取程式碼,並靈活支援不同模型之間的特徵共享。在排序服務中上線一種模型成本很低,只需要提供模型檔案和特徵配置檔案即可,後續我們將會對排序配置進行Web化,簡化上線流程。目前,我們的排序服務中運行了基於LR、XGBoost、FM、XGBoost+LR、XGBoost+FM、DNN的幾十個排序模型。

  • ABTest實驗中心。我們設計了一套靈活通用的ABTest實驗平臺(內部稱作“日晷”)來支援推薦系統的策略迭代,它包括流量控制、實時效果資料統計和視覺化等功能,支援使用者在Web頁面上配置實驗和流量,並能展示實時效果資料。這套實驗平臺不僅可以應用於推薦系統,還可以用於任何其它需要做ABTest實驗的業務系統中,它支援多層ABTest實驗,能充分利用每份流量去完成業務迭代。例如我們的推薦系統ABTest實驗就包含召回、排序、規則和展示四層,不同層之間實現了流量的重新打散,保證了不同層之間實驗的正交性。當請求到達我們的推薦系統時,推薦主體服務便請求“日晷”以獲得該請求對應的召回號、排序號、規則號和展示號等實驗引數,之後該請求便會被這些實驗引數打上標記,貫穿於後續的推薦流程,決定每層中將走哪部分邏輯,最終這些實驗引數會記錄到後臺和客戶端埋點日誌中,用於最終的實驗效果統計。

                          

接入層直接和客戶端互動,從客戶端接收請求並呼叫推薦主體服務獲得推薦帖子id列表,然後查詢出帖子詳細屬性返回給客戶端做展示。在大部分推薦場景中,接入層由業務方維護,可能是PHP或Java實現的http介面;也有少部分場景的接入層是我們自主維護,我們採用58自研的MVC框架WF實現了相關http介面。

       我們採用58自研的RPC框架SCF實現了上述微服務架構的推薦系統,採用58自研的監控系統WMonitor實現了推薦系統的立體監控,整個技術棧是Java。我們採用多執行緒、非同步、快取、JVM調優、降級、限流等措施保證了推薦系統的穩定和高可用,目前我們的推薦系統日均處理數億的推薦請求,平均耗時約30毫秒。

資料

       這裡的資料主要指推薦埋點資料和推薦效果資料:埋點資料是推薦系統的基石,模型訓練和效果資料統計都基於埋點資料,需保證埋點資料的正確無誤;效果資料是對推薦系統的評價,指引推薦策略的迭代,構建完備的效果資料體系至關重要。

       我們的推薦埋點日誌資料包括曝光日誌、點選日誌、轉化日誌和頁面停留時長日誌等,這些日誌資料都需要客戶端通過埋點來產生。這裡簡單解釋一下這些操作的含義:客戶端請求一次推薦介面得到推薦結果列表叫做一次曝光;使用者點選推薦結果列表上的某條帖子進入帖子詳情頁叫做一次點選;使用者在帖子詳情頁上進行微聊、打電話、收藏等操作叫做轉化;使用者在帖子詳情頁上的閱讀時間叫做頁面停留時長。這裡的曝光、點選和轉化是一個漏斗,運算元量是逐漸遞減的趨勢。由於58同城上使用者對帖子的訪問可能來源於推薦、搜尋和運營活動頁等場景,為了標識出推薦產生的點選/轉化/停留時長,我們需要在埋點中加入推薦相關的引數。我們將埋點引數設計成一個固定格式的字串,它包含了曝光唯一序列號、推薦位標識、召回號、排序號、規則號、展示號、帖子id列表、帖子id等欄位,這些欄位將會作用於機器學習模型訓練樣本生成和推薦效果統計中。埋點引數主要分為列表引數和單貼引數兩類:推薦介面返回一個帖子列表,會對應返回一個列表引數,包含了曝光序列號、推薦位標識、召回號、排序號、規則號、展示號、帖子id列表等欄位;返回的帖子列表中,每個帖子會對應返回一個單貼引數,包含曝光序列號、推薦位標識、召回號、排序號、規則號、展示號、帖子id等欄位。客戶端得到推薦介面返回的埋點引數後,會將列表引數埋入到曝光日誌中,將單貼引數埋入到點選日誌、轉化日誌和停留時長日誌當中,注意這裡埋點時需要推薦列表頁向帖子詳情頁傳遞單貼引數,一般需要通過修改跳轉協議來實現。最終埋點日誌中有了這些引數後,我們便可基於曝光唯一序列號將曝光、點選、轉化、時長資料join起來,產生模型訓練樣本以及漏斗效果資料。值得一提的是,我們採取透傳的方式在推薦後臺、接入層、客戶端間傳遞埋點引數字串,所有埋點引數由推薦系統後臺生成,接入層和客戶端均不做任何處理。埋點引數僅由我們推薦一方負責,這樣能夠避免多方改動埋點引數,從而減少埋點錯誤的可能性,由於是透傳處理,也便於今後埋點引數的擴充套件。

       埋點資料是推薦系統的基石,不能有遺漏或者錯誤,這就要求我們嚴格把控開發測試流程,尤其是APP上的埋點,若發版之後發現有錯誤,便要等到下一次發版時解決。客戶端開發和測試同事不清楚埋點引數的含義但熟練掌握測試環境部署及擁有Android和IOS測試機,而推薦後臺同事清楚埋點引數含義但對測試環境較生疏並缺乏測試機,因此我們總結出了測試同事負責環境部署、推薦後臺同事負責檢驗埋點引數的測試流程,詳細流程如下圖所示。此外,58同城上的APP開發比較複雜,不同產品線各自開發自己的APP業務模組,APP平臺方開發主模組,每次發版前都有一個整合階段,合併所有業務方提交的程式碼,產生最終的APP包,整合階段很可能會發生業務方埋點未生效的情況。因此,我們的埋點測試包括業務方內部測試和整合測試兩個階段,以保證埋點萬無一失。

                         

我們的推薦效果資料是一個多維資料集,我們主要關注推薦位上的點選、轉化、停留時長等指標。日常工作中我們需要從不同業務線、不同客戶端、不同推薦位、不同推薦演算法等多個維度去分析這些指標資料,例如我們會觀察房產和車在相同推薦位上的資料對比、猜你喜歡場景上不同召回或排序演算法的資料對比、二手房詳情頁在Android和IPhone上資料對比等。各種資料分析對比能幫助我們優化推薦策略,甚至能發現某些業務線功能邏輯上的隱藏BUG,例如在我們推薦專案攻堅階段,我們通過分析比較二手房詳情頁在Android和IPhone兩端的推薦效果,發現了IPhone上詳情頁瀏覽回退的BUG,最終反饋給業務方並解決了該問題,該BUG的解決使得我們在二手房詳情頁推薦位上的推薦點選量提高了數十萬。

我們從離線和實時兩方面構建推薦效果資料,資料統計流程如下圖所示:

                         

早期,離線效果資料統計是通過 MapReduce + Hive + MySQL 來實現的,我們首先會編寫MapReduce程式對原始埋點日誌進行抽取生成Hive表,然後會編寫大量的Hive SQL來統計各類指標資料,並將結果資料寫入MySQL資料表,最終做視覺化展示和郵件報表。由於我們比較的維度和指標多,Hive SQL語句的編寫消耗了我們不少人力。在資料平臺部門部署了Kylin多維分析系統後,我們將效果資料統計工作遷移到了Kylin上,我們只需要設計好Hive源資料表,並設定好維度和度量,Kylin便能根據維度和度量來自動預計算結果資料,這省去了我們編寫Hive SQL的工作,大大提高了效率。關於如何利用Kylin構建多維資料集可以參考此文《基於Kylin的推薦系統效果評價系統》。

實時效果資料我們採用Storm + HBase 來計算,實時效果資料主要用於異常埋點監控、新上線推薦演算法效果快速反饋、模型異常監控等,我們實現了一個包含較少維度的多維資料統計,今後我們將嘗試引入Druid等實時多維分析系統來完善推薦實時效果資料的建設。

總結

本文介紹了58同城智慧推薦系統在演算法、工程和資料三方面的技術演進。我們在最近一年加快了推薦業務的迭代速度,接入了房產、車等業務線在APP、PC、M三端共計近百個推薦位,我們的推薦點選佔比指標(推薦位上產生的點選量在總體點選量中的佔比)相比一年之前提高了2~3倍,達到了20%~30%,每天能夠產生數千萬的推薦點選量,為業務線帶來了流量提升。

任何推薦系統的發展必會經歷推薦位擴充和推薦演算法深入優化兩個階段,流量指標可以通過擴充推薦位來快速提高,當推薦位穩定之後,就需要依賴更加深入的演算法優化來繼續提高指標,而此時的效果提升也會相對緩慢。目前,我們的流量指標已相對穩定,我們會更進一層去關注轉化指標,提高使用者進入帖子之後與發帖人進行微聊或電話溝通的可能性,幫助使用者找到真正有用的資訊。