引言
我們正處在一個知識爆炸的時代,伴隨著信息量的劇增和人工智能的蓬勃發(fā)展,互聯(lián)網(wǎng)公司越發(fā)具有強烈的個性化、智能化信息展示的需求。而信息展示個性化的典型應用主要包括搜索列表、推薦列表、廣告展示等等。
很多人不知道的是,看似簡單的個性化信息展示背后,涉及大量的數(shù)據(jù)、算法以及工程架構(gòu)技術(shù),這些足以讓大部分互聯(lián)網(wǎng)公司望而卻步。究其根本原因,個性化信息展示背后的技術(shù)是排序?qū)W習問題(Learning to Rank)。顯然,市面上大部分關(guān)于排序?qū)W習的文章,要么偏算法、要么偏工程。雖然算法方面有一些系統(tǒng)性的介紹文章,但往往對讀者的數(shù)學能力要求比較高,也偏學術(shù)論文,對于非算法同學來說門檻非常高。而大部分工程方面的文章也比較粗糙,基本上停留在Google的Two-Phase Scheme階段,從工程實施的角度來說,遠遠還不夠具體。
對于那些由系統(tǒng)開發(fā)工程師負責在線排序架構(gòu)的團隊來說,本文會采用通俗的例子和類比方式來闡述算法部分,希望能夠幫助大家更好地理解和掌握排序?qū)W習的核心概念。如果是算法工程師團隊的同學,可以忽略算法部分的內(nèi)容。本文的架構(gòu)部分闡述了美團點評到店餐飲業(yè)務線上運行的系統(tǒng),可以作為在線排序系統(tǒng)架構(gòu)設(shè)計的參考原型直接使用。該架構(gòu)在服務治理、分層設(shè)計的理念,對于保障在線排序架構(gòu)的高性能、高可用性、易維護性也具有一定的參考價值。包括很多具體環(huán)節(jié)的實施方案也可以直接進行借鑒,例如流量分桶、流量分級、特征模型、級聯(lián)模型等等。
總之,讓開發(fā)工程師能夠理解排序?qū)W習算法方面的核心概念,并為在線架構(gòu)實施提供細顆粒度的參考架構(gòu),是本文的重要目標。
算法部分機器學習涉及優(yōu)化理論、統(tǒng)計學、數(shù)值計算等多個領(lǐng)域。這給那些希望學習機器學習核心概念的系統(tǒng)開發(fā)工程師帶來了很大的障礙。不過,復雜的概念背后往往蘊藏著樸素的道理。本節(jié)將嘗試采用通俗的例子和類比方式,來對機器學習和排序?qū)W習的一些核心概念進行揭秘。
機器學習 什么是機器學習?典型的機器學習問題,如下圖所示:
機器學習模型或算法(Model/Algorithm)會根據(jù)觀察到的特征值(Feature)進行預測,給出預測結(jié)果或者目標(Prediction/Target)。這就像是一個函數(shù)計算過程,對于特定X值(Feature),算法模型就像是函數(shù),最終的預測結(jié)果是Y值。不難理解,機器學習的核心問題就是如何得到預測函數(shù)。
Wikipedia的對機器學習定義如下:
“Machine learning is a subset of artificial intelligence in the field of computer science that often uses statistical techniques to give computers the ability to learn with data, without being explicitly programmed.”
機器學習的最重要本質(zhì)是從數(shù)據(jù)中學習,得到預測函數(shù)。人類的思考過程以及判斷能力本質(zhì)上也是一種函數(shù)處理。從數(shù)據(jù)或者經(jīng)驗中學習,對于人類來說是一件再平常不過的事情了。例如人們通過觀察太陽照射物體影子的長短而發(fā)明了日晷,從而具備了計時和制定節(jié)氣的能力。古埃及人通過尼羅河水的漲落發(fā)明了古埃及歷法。
又比如人們通過觀察月亮形狀的變化而發(fā)明了陰歷。
如果機器能夠像人一樣具備從數(shù)據(jù)中學習的能力,從某種意義上講,就具備了一定的“智能”?,F(xiàn)在需要回答的兩個問題就是:
到底什么是“智能”?
如何讓機器具備智能?
什么是智能?在回答這個問題之前,我們先看看傳統(tǒng)的編程模式為什么不能稱之為“智能”。傳統(tǒng)的編程模式如下圖所示,它一般要經(jīng)歷如下幾個階段:
人類通過觀察數(shù)據(jù)(Data)總結(jié)經(jīng)驗,轉(zhuǎn)化成知識(Knowledge)。
人類將知識轉(zhuǎn)化成規(guī)則(Rule)。
工程師將規(guī)則轉(zhuǎn)化成計算機程序(Program)。
在這種編程模式下,如果一個問題被規(guī)則覆蓋,那么計算機程序就能處理。對于規(guī)則不能覆蓋的問題,只能由人類來重新思考,制定新規(guī)則來解決。所以在這里“智能”角色主要由人類來承擔。人類負責解決新問題,所以傳統(tǒng)的程序本身不能稱之為“智能”。
所以,“智能”的一個核心要素就是“舉一反三”。
如何讓機器具備智能?在討論這個問題之前,可以先回顧一下人類是怎么掌握“舉一反三”的能力的?基本流程如下:
老師給學生一些題目,指導學生如何解題。學生努力掌握解題思路,盡可能讓自己的答案和老師給出的答案一致。
學生需要通過一些考試來證明自己具備“舉一反三”的能力。如果通過了這些考試,學生將獲得畢業(yè)證書或者資格從業(yè)證書。
學生變成一個從業(yè)者之后將會面臨并且處理很多之前沒有碰到過的新問題。
機器學習專家從人類的學習過程中獲得靈感,通過三個階段讓機器具備“舉一反三”的能力。這三個階段是:訓練階段(Training)、測試階段(Testing)、推導階段(Inference)。下面逐一進行介紹:
訓練階段訓練階段如下圖所示:
人類給機器學習模型一些訓練樣本(X,Y),X代表特征,Y代表目標值。這就好比老師教學生解題,X代表題目,Y代表標準答案。
機器學習模型嘗試想出一種方法解題。
在訓練階段,機器學習的目標就是讓損失函數(shù)值最小。類比學生嘗試讓自己解題的答案和老師給的標準答案差別最小,思路如出一轍。
測試階段測試階段如下圖所示:
人類給訓練好的模型一批完全不同的測試樣本(X,Y)。這就好比學生拿到考試試卷。
模型進行推導。這個過程就像學生正在考試答題。
人類要求測試樣本的總損失函數(shù)值低于設(shè)定的最低目標值。這就像學校要求學生的考試成績必須及格一樣。
推導階段推導階段如下圖所示:
在這個階段機器學習模型只能拿到特征值X,而沒有目標值。這就像工作中,人們只是在解決一個個的問題,但不知道正確的結(jié)果到底是什么。
在推導階段,機器學習的目標就是預測,給出目標值。
排序?qū)W習 什么是排序?qū)W習?Wikipedia的對排序?qū)W習的定義如下:
“Learning to rank is the application of machine learning, typically supervised, semi-supervised or reinforcement learning, in the construction of ranking models for information retrieval systems. Training data consists of lists of items with some partial order specified between items in each list. This order is typically induced by giving a numerical or ordinal score or a binary judgment (e.g. "relevant" or "not relevant") for each item. The ranking model"s purpose is to rank, i.e. produce a permutation of items in new, unseen lists in a way which is "similar" to rankings in the training data in some sense.”
排序?qū)W習是機器學習在信息檢索系統(tǒng)里的應用,其目標是構(gòu)建一個排序模型用于對列表進行排序。排序?qū)W習的典型應用包括搜索列表、推薦列表和廣告列表等等。
列表排序的目標是對多個條目進行排序,這就意味著它的目標值是有結(jié)構(gòu)的。與單值回歸和單值分類相比,結(jié)構(gòu)化目標要求解決兩個被廣泛提起的概念:
列表評價指標
列表訓練算法
列表評價指標以關(guān)鍵詞搜索返回文章列表為例,這里先分析一下列表評價指標要解決什么挑戰(zhàn)。
第一個挑戰(zhàn)就是定義文章與關(guān)鍵詞之間的相關(guān)度,這決定了一篇文章在列表中的位置,相關(guān)度越高排序就應該越靠前。
第二個挑戰(zhàn)是當列表中某些文章沒有排在正確的位置時候,如何給整個列表打分。舉個例子來說,假如對于某個關(guān)鍵詞,按照相關(guān)性的高低正確排序,文檔1、2、3、4、5應該依次排在前5位?,F(xiàn)在的挑戰(zhàn)就是,如何評估“2,1,3,4,5”和“1,2,5,4,3”這兩個列表的優(yōu)劣呢?
列表排序的評價指標體系總來的來說經(jīng)歷了三個階段,分別是Precision and Recall、Discounted Cumulative Gain(DCG)和Expected Reciprocal Rank(ERR)。我們逐一進行講解。
Precision and Recall(P-R)本評價體系通過準確率(Precision)和召回率(Recall)兩個指標來共同衡量列表的排序質(zhì)量。對于一個請求關(guān)鍵詞,所有的文檔被標記為相關(guān)和不相關(guān)兩種。
Precision的定義如下:
Recall的定義如下:
舉個列子來說,對于某個請求關(guān)鍵詞,有200篇文章實際相關(guān)。某個排序算法只認為100篇文章是相關(guān)的,而這100篇文章里面,真正相關(guān)的文章只有80篇。按照以上定義:
準確率=80/100=0.8
召回率=80/200=0.4。
Discounted Cumulative Gain(DCG)P-R的有兩個明顯缺點:
所有文章只被分為相關(guān)和不相關(guān)兩檔,分類顯然太粗糙。
沒有考慮位置因素。
DCG解決了這兩個問題。對于一個關(guān)鍵詞,所有的文檔可以分為多個相關(guān)性級別,這里以rel1,rel2...來表示。文章相關(guān)性對整個列表評價指標的貢獻隨著位置的增加而對數(shù)衰減,位置越靠后,衰減越嚴重?;贒CG評價指標,列表前p個文檔的評價指標定義如下:
對于排序引擎而言,不同請求的結(jié)果列表長度往往不相同。當比較不同排序引擎的綜合排序性能時,不同長度請求之間的DCG指標的可比性不高。目前在工業(yè)界常用的是Normalized DCG(nDCG),它假定能夠獲取到某個請求的前p個位置的完美排序列表,這個完美列表的分值稱為Ideal DCG(IDCG),nDCG等于DCG與IDCG比值。所以nDCG是一個在0到1之間的值。
nDCG的定義如下:
IDCG的定義如下:
|REL|代表按照相關(guān)性排序好的最多到位置p的結(jié)果列表。
Expected Reciprocal Rank(ERR)與DCG相比,除了考慮位置衰減和允許多種相關(guān)級別(以R1,R2,R3...來表示)以外,ERR更進了一步,還考慮了排在文檔之前所有文檔的相關(guān)性。舉個例子來說,文檔A非常相關(guān),排在第5位。如果排在前面的4個文檔相關(guān)度都不高,那么文檔A對列表的貢獻就很大。反過來,如果前面4個文檔相關(guān)度很大,已經(jīng)完全解決了用戶的搜索需求,用戶根本就不會點擊第5個位置的文檔,那么文檔A對列表的貢獻就不大。
ERR的定義如下:
列表訓練算法做列表排序的工程師們經(jīng)常聽到諸如Pointwise、Pairwise和Listwise的概念。這些是什么東西呢,背后的原理又是什么呢?這里將逐一解密。
仍然以關(guān)鍵詞搜索文章為例,排序?qū)W習算法的目標是為給定的關(guān)鍵詞對文章列表進行排序。做為類比,假定有一個學者想要對各科學生排名進行預測。各種角色的對應關(guān)系如下:
首先我們要告訴學者每個學生的各種屬性,這就像我們要告訴排序算法文檔特征。對于目標值,我們卻有三種方式來告訴學者:
對于每個學科,我們可以告訴學者每個學生的成績。比較每個學生的成績,學者當然可以算出每個學生的最終排名。這種訓練方法被稱為Pointwise。對于Pointwise算法,如果最終預測目標是一個實數(shù)值,就是一個回歸問題。如果目標是概率預測,這就是一個分類問題,例如CTR預估。
對于每個學科,我們可以告訴學者任意兩個學生的相互排名。根據(jù)學生之間排名的情況,學者也可以算出每個學生的最終排名。這種訓練方法被稱為Pairwise。Pairwise算法的目標是減少逆序的數(shù)量,所以是個二分類問題。
對于每個學科,我們可以直接告訴學者所有學生的整體排名。這種訓練方法被稱為Listwise。Listwise算法的目標往往是直接優(yōu)化nDCG、ERR等評價指標。
這三種方法表面看上去有點像玩文字游戲,但是背后卻是工程師和科學家們不斷探索的結(jié)果。最直觀的方案是Pointwise算法,例如對于廣告CTR預估,在訓練階段需要標注某個文檔的點擊概率,這相對來說容易。Pairwise算法一個重要分支是Lambda系列,包括LambdaRank、LambdaMart等,它的核心思想是:很多時候我們很難直接計算損失函數(shù)的值,但卻很容易計算損失函數(shù)梯度(Gradient)。這意味著我們很難計算整個列表的nDCG和ERR等指標,但卻很容易知道某個文檔應該排的更靠前還是靠后。Listwise算法往往效果最好,但是如何為每個請求對所有文檔進行標注是一個巨大的挑戰(zhàn)。
在線排序架構(gòu)典型的信息檢索包含兩個階段:索引階段和查詢階段。這兩個階段的流程以及相互關(guān)系可以用下圖來表示:
索引階段的工作是由索引器(Indexer)讀取文檔(Documents)構(gòu)建索引(Index)。
查詢階段讀取索引做為召回,然后交給Topn Retriever進行粗排,在粗排后的結(jié)果里面將前n個文檔傳給Reranker進行精排。這樣一個召回、粗排、精排的架構(gòu)最初是由Google提出來的,也被稱為“Two-Phase Scheme”。
索引部分屬于離線階段,這里重點講述在線排序階段,即查詢階段。
三大挑戰(zhàn)在線排序架構(gòu)主要面臨三方面的挑戰(zhàn):特征、模型和召回。
特征挑戰(zhàn)包括特征添加、特征算子、特征歸一化、特征離散化、特征獲取、特征服務治理等。
模型挑戰(zhàn)包括基礎(chǔ)模型完備性、級聯(lián)模型、復合目標、A/B實驗支持、模型熱加載等。
召回挑戰(zhàn)包括關(guān)鍵詞召回、LBS召回、推薦召回、粗排召回等。
三大挑戰(zhàn)內(nèi)部包含了非常多更細粒度的挑戰(zhàn),孤立地解決每個挑戰(zhàn)顯然不是好思路。在線排序作為一個被廣泛使用的架構(gòu)值得采用領(lǐng)域模型進行統(tǒng)一解決。Domain-driven design(DDD)的三個原則分別是:領(lǐng)域聚焦、邊界清晰、持續(xù)集成。
基于以上分析,我們構(gòu)建了三個在線排序領(lǐng)域模型:召回治理、特征服務治理和在線排序分層模型。
召回治理經(jīng)典的Two-Phase Scheme架構(gòu)如下圖所示,查詢階段應該包含:召回、粗排和精排。但從領(lǐng)域架構(gòu)設(shè)計的角度來講,粗排對于精排而言也是一種召回。和基于傳統(tǒng)的文本搜索不同,美團點評這樣的O2O公司需要考慮地理位置和距離等因素,所以基于LBS的召回也是一種召回。與搜索不同,推薦召回往往基于協(xié)同過濾來完成的,例如User-Based CF和Item-Based CF。
綜上所述,召回總體而言分成四大類:
關(guān)鍵詞召回,我們采用Elasticsearch解決方案。
距離召回,我們采用K-D tree的解決方案。
粗排召回。
推薦類召回。
特征服務治理傳統(tǒng)的視角認為特征服務應該分為用戶特征(User)、查詢特征(Query)和文檔特征(Doc),如下圖:
這是比較純粹的業(yè)務視角,并不滿足DDD的領(lǐng)域架構(gòu)設(shè)計思路。由于特征數(shù)量巨大,我們沒有辦法為每個特征設(shè)計一套方案,但是我們可以把特征進行歸類,為幾類特征分別設(shè)計解決方案。每類技術(shù)方案需要統(tǒng)一考慮性能、可用性、存儲等因素。從領(lǐng)域視角,特征服務包含四大類:
列表類特征。一次請求要求返回實體列表特征,即多個實體,每個實體多個特征。這種特征建議采用內(nèi)存列表服務,一次性返回所有請求實體的所有特征。避免多次請求,從而導致數(shù)量暴增,造成系統(tǒng)雪崩。
實體特征。一次請求返回單實體的多個特征。建議采用Redis、Tair等支持多級的Key-Value服務中間鍵提供服務。
上下文特征。包括召回靜態(tài)分、城市、Query特征等。這些特征直接放在請求內(nèi)存里面。
相似性特征。有些特征是通過計算個體和列表、列表和列表的相似度而得到的。建議提供多帶帶的內(nèi)存計算服務,避免這類特征的計算影響在線排序性能。本質(zhì)上這是一種計算轉(zhuǎn)移的設(shè)計。
在線排序分層模型如下圖所示,典型的排序流程包含六個步驟:場景分發(fā)(Scene Dispatch)、流量分配(Traffic Distribution)、召回(Recall)、特征抽?。‵eature Retrieval)、預測(Prediction)、排序(Ranking)等等。
按照DDD的設(shè)計原則,我們設(shè)計了如下在線排序分層模型,包括:場景分發(fā)(Scene Dispatch)、模型分發(fā)(Model Distribution)、排序(Ranking)、特征管道(Feature Pipeline)、預測管道(Prediction Pipeline)。我們將逐一進行介紹。
場景分發(fā)(Scene Dispatch)場景分發(fā)一般是指業(yè)務類型的分發(fā)。對于美團點評而言包括:分平臺、分列表、分使用場景等。如下圖所示:
模型分發(fā)(Model Distribution)模型分發(fā)的目標是把在線流量分配給不同的實驗模型,具體而言要實現(xiàn)三個功能:
為模型迭代提供在線流量,負責線上效果收集、驗證等。
A/B測試,確保不同模型之間流量的穩(wěn)定、獨立和互斥、確保效果歸屬唯一。
確保與其他層的實驗流量的正交性。
流量的定義是模型分發(fā)的一個基礎(chǔ)問題。典型的流量包括:訪問、用戶和設(shè)備。
如何讓一個流量穩(wěn)定地映射到特定模型上面,流量之間是否有級別?這些是模型分發(fā)需要重點解決的問題。
流量分桶原理采用如下步驟將流量分配到具體模型上面去:
把所有流量分成N個桶。
每個具體的流量Hash到某個桶里面去。
給每個模型一定的配額,也就是每個策略模型占據(jù)對應比例的流量桶。
所有策略模型流量配額總和為100%。
當流量和模型落到同一個桶的時候,該模型擁有該流量。
舉個例子來說,如上圖所示,所有流量分為32個桶,A、B、C三個模型分別擁有37.5%、25%和37.5%的配額。對應的,A、B、C應該占據(jù)12、8和12個桶。
為了確保模型和流量的正交性,模型和流量的Hash Key采用不同的前綴。
流量分級每個團隊的模型分級策略并不相同,這里只給出一個建議模型流量分級:
基線流量。本流量用于與其他流量進行對比,以確定新模型的效果是否高于基準線,低于基準線的模型要快速下線。另外,主力流量相對基線流量的效果提升也是衡量算法團隊貢獻的重要指標。
實驗流量。該流量主要用于新實驗模型。該流量大小設(shè)計要注意兩點:第一不能太大而傷害線上效果;第二不能太小,流量太小會導致方差太大,不利于做正確的效果判斷。
潛力流量。如果實驗流量在一定周期內(nèi)效果比較好,可以升級到潛力流量。潛力流量主要是要解決實驗流量方差大帶來的問題。
主力流量。主力流量只有一個,即穩(wěn)定運行效果最好的流量。如果某個潛力流量長期好于其他潛力流量和主力流量,就可以考慮把這個潛力流量升級為主力流量。
做實驗的過程中,需要避免新實驗流量對老模型流量的沖擊。流量群體對于新模型會有一定的適應期,而適應期相對于穩(wěn)定期的效果一般會差一點。如果因為新實驗的上線而導致整個流量群體的模型都更改了,從統(tǒng)計學的角度講,模型之間的對比關(guān)系沒有變化。但這可能會影響整個大盤的效果,成本很高。
為了解決這個問題,我們的流量分桶模型優(yōu)先為模型列表前面的模型分配流量,實驗模型盡量放在列表尾端。這樣實驗模型的頻繁上下線不影響主力和潛力流量的用戶群體。當然當發(fā)生模型流量升級的時候,很多流量用戶的服務模型都會更改。這種情況并不是問題,因為一方面我們在嘗試讓更多用戶使用更好的模型,另一方面固定讓一部分用戶長期使用實驗流量也是不公平的事情。
排序(Ranking)排序模塊是特征模塊和預測模塊的容器,它的主要職責如下:
獲取所有列表實體進行預測所需特征。
將特征交給預測模塊進行預測。
對所有列表實體按照預測值進行排序。
特征管道(Feature Pipeline)特征管道包含特征模型(Feature Model)、表達式(Expression)、原子特征(Atomic Feature)、 特征服務代理(Feature Proxy)、特征服務(Feature Service)。如下圖所示:
特征管道要解決兩個核心問題:
給定特征名獲取對應特征值。這個過程很復雜,要完成特征名->特征服務->特征類->特征值的轉(zhuǎn)化過程。
特征算子問題。模型使用的特征往往是對多個原子特征進行復合運算后的結(jié)果。另外,特征離散化、歸一化也是特征算子需要解決的問題。
完整的特征獲取流程如下圖所示,具體的流程如下:
Ranking模塊從FeatureModel里面讀取所有的原始特征名。
Ranking將所有的原始特征名交給Feature Proxy。
Feature Proxy根據(jù)特征名的標識去調(diào)用對應的Feature Service,并將原始特征值返回給Ranking模塊。
Ranking模塊通過Expression將原始特征轉(zhuǎn)化成復合特征。
Ranking模塊將所有特征交給級聯(lián)模型做進一步的轉(zhuǎn)換。
特征模型(Feature Model)我們把所有與特征獲取和特征算子的相關(guān)信息都放在一個類里面,這個類就是FeatureModel,定義如下:
//包含特征獲取和特征算子計算所需的meta信息 public class FeatureModel { //這是真正用在Prediction里面的特征名 private String featureName; //通過表達式將多種原子特征組合成復合特征。 private IExpression expression; //這些特征名是真正交給特征服務代理(Feature Proxy)去從服務端獲取特征值的特征名集合。 private Set表達式(Expression)originalFeatureNames; //用于指示特征是否需要被級聯(lián)模型轉(zhuǎn)換 private boolean isTransformedFeature; //是否為one-hot特征 private boolean isOneHotIdFeature; //不同one-hot特征之間往往共享相同的原始特征,這個變量>用于標識原始特征名。 private String oneHotIdKey; //表明本特征是否需要歸一化 private boolean isNormalized; }
表達式的目的是為了將多種原始特征轉(zhuǎn)換成一個新特征,或者對單個原始特征進行運算符轉(zhuǎn)換。我們采用前綴法表達式(Polish Notation)來表示特征算子運算。例如表達式(5-6)*7的前綴表達式為* - 5 6 7。
復合特征需要指定如下分隔符:
復合特征前綴。區(qū)別于其他類型特征,我們以“$”表示該特征為復合特征。
表達式各元素之間的分隔符,采用“_”來標識。
用“O”表示運算符前綴。
用“C”表示常數(shù)前綴。
用“V”表示變量前綴。
例如:表達式v1 + 14.2 + (2*(v2+v3)) 將被表示為 $O+_O+_Vv1_C14.2_O*_C2_O+_Vv2_Vv3
原子特征(Atomic Feature)原子特征(或者說原始特征)包含特征名和特征值兩個部分。原子特征的讀取需要由4種實體類共同完成:
POJO用于存儲特征原始值。例如DealInfo保存了所有與Deal實體相關(guān)的特征值,包括Price、maxMealPerson、minMealPerson等等。
ScoringValue用于存儲從POJO中返回的特征值。特征值包含三種基本類型,即數(shù)量型(Quantity)、序數(shù)型(Ordinal)、類別型(Categorical)。
ScoreEnum實現(xiàn)特征名到特征值的映射。每類原子特征對應于一個ScoreEnum類,特征名通過反射(Reflection)的方式來構(gòu)建對應的ScoreEnum類。ScoreEnum類和POJO一起共同實現(xiàn)特征值的讀取。
FeatureScoreEnumContainer用于保存一個算法模型所需所有特征的ScoreEnum。
一個典型的例子如下圖所示:
DealInfo是POJO類。
DealInfoScoreEnum是一個ScoreEnum基類。對應于平均用餐人數(shù)特征、價格等特征,我們定義了DIAveMealPerson和DIPrice的具體ScoreEnum類。
FeatureScoreEnumContainer用于存儲某個模型的所有特征的ScoreEnum。
復雜系統(tǒng)設(shè)計需要充分的利用語言特性和設(shè)計模式。建議的優(yōu)化點有三個:
為每個原子特征定義一個ScoreEnum類會導致類數(shù)量暴增。優(yōu)化方式是ScoreEnum基類定義為Enum類型,每個具體特征類為一個枚舉值,枚舉值繼承并實現(xiàn)枚舉類的方法。
FeatureScoreEnumContainer采用Build設(shè)計模式將一個算法模型的所需特征轉(zhuǎn)換成ScoreEnum集合。
ScoreEnum從POJO類中讀取具體特征值采用的是Command模式。
這里稍微介紹一下Command設(shè)計模式。Command模式的核心思想是需求方只要求拿到相關(guān)信息,不關(guān)心誰提供以及怎么提供。具體的提供方接受需求方的需求,負責將結(jié)果交給需求方。
在特征讀取里面,需求方是模型,模型僅僅提供一個特征名(FeatureName),不關(guān)心怎么讀取對應的特征值。具體的ScoreEnum類是具體的提供方,具體的ScoreEnum從POJO里面讀取特定的特征值,并轉(zhuǎn)換成ScoringValue交給模型。
特征服務代理(Feature Proxy)特征服務代理負責遠程特征獲取實施,具體的過程包括:
每一大類特征或者一種特征服務有一個FeatureProxy,具體的FeatureProxy負責向特征服務發(fā)起請求并獲取POJO類。
所有的FeatureProxy注冊到FeatureServiceContainer類。
在具體的一次特征獲取中,F(xiàn)eatureServiceContainer根據(jù)FeatureName的前綴負責將特征獲取分配到不同的FeatureProxy類里面。
FeatureProxy根據(jù)指定的實體ID列表和特征名從特征服務中讀取POJO列表。只有對應ID的指定特征名(keys)的特征值才會被賦值給POJO。這就最大限度地降低了網(wǎng)絡(luò)讀取的成本。
預測管道(Prediction Pipeline)預測管道包含:預測(Prediction)、級聯(lián)模型(Cascade Model)、表達式(Expression)、特征轉(zhuǎn)換(Transform)、計分(Scoring)和原子模型(Atomic Model)。
預測(Prediction)預測本質(zhì)上是對模型的封裝。它負責將每個列表實體的特征轉(zhuǎn)化成模型需要的輸入格式,讓模型進行預測。
級聯(lián)模型(Cascade Model)我們構(gòu)建級聯(lián)模型主要是基于兩方面的觀察:
基于Facebook的《Practical Lessons from Predicting Clicks on Ads at Facebook》的Xgboost+LR以及最近很熱門的Wide&Deep表明,對一些特征,特別是ID類特征通過樹模型或者NN模型進行轉(zhuǎn)化,把轉(zhuǎn)化后的值做為特征值交給預測模型進行預測,往往會能實現(xiàn)更好的效果。
有些訓練目標是復合目標,每個子目標需要通過不同的模型進行預測。這些子目標之間通過一個簡單的表達式計算出最終的預測結(jié)果。
舉例如下圖所示,我們自上而下進行講解:
該模型有UserId、CityId、UserFeature、POI等特征。
UserId和CityId特征分別通過GBDT和NN模型進行轉(zhuǎn)換(Transform)。
轉(zhuǎn)換后的特征和UserFeature、POI等原始特征一起交給NN和LR模型進行算分(Scoring)。
最終的預測分值通過表達式Prediction Score = αNNScore + βLRScore/(1+γ)來完成。表達式中的 α 、β和γ是事先設(shè)置好的值。
原子模型(Atomic Model)在這里原子模型指的是一種原子計算拓撲結(jié)構(gòu),比如線性模型、樹模型和網(wǎng)絡(luò)模型。
常用的模型像Logistic Regression和Linear Regression都是線性模型。GBDT、Random Forest都是樹模型。MLP、CNN、RNN都是網(wǎng)絡(luò)模型。
這里定義的原子模型主要的目的是為了工程實施的便利。一個模型被認定為原子模型有如下兩個原因:
該模型經(jīng)常做為獨立預測模型被使用。
該模型有比較完整的實現(xiàn)代碼。
總結(jié)本文總結(jié)了作者在美團點評解決到店餐飲個性化信息展示的相關(guān)經(jīng)驗,從算法和架構(gòu)兩方面進行闡述。在算法部分,文章采用通俗的例子和類比方式進行講解,希望非算法工程師能夠理解關(guān)鍵的算法概念。架構(gòu)部分比較詳細地闡述了到店餐飲的排序架構(gòu)。
根據(jù)我們所掌握的知識,特征治理和召回治理的思路是一種全新的視角,這對于架構(gòu)排序系統(tǒng)設(shè)計有很大的幫助。這種思考方式同樣也適用于其他領(lǐng)域模型的構(gòu)建。與Google提供的經(jīng)典Two-Phase Scheme架構(gòu)相比,在線排序分層模型提供了更細顆粒度的抽象原型。該原型細致的闡述了包括分流、A/B測試、特征獲取、特征算子、級聯(lián)模型等一系列經(jīng)典排序架構(gòu)問題。同時該原型模型由于采用了分層和層內(nèi)功能聚焦的思路,所以它比較完美地體現(xiàn)了DDD的三大設(shè)計原則,即領(lǐng)域聚焦、邊界清晰、持續(xù)集成。
作者簡介劉丁,曾就職于Amazon、TripAdvisor。2014年加入美團,先后負責美團推薦系統(tǒng)、智能篩選系統(tǒng)架構(gòu)、美團廣告系統(tǒng)的架構(gòu)和上線、完成美團廣告運營平臺的搭建。目前負責到店餐飲算法策略方向,推進AI在到店餐飲各領(lǐng)域的應用。
參考文章:[1]Gamma E, Helm R, Johnson R, et al. Design Patterns-Elements of Reusable Object-Oriented Software. Machinery Industry, 2003.
[2]Wikipedia,Learning to rank.
[3]Wikipedia,Machine learning.
[4]Wikipedia,Precision and recall.
[5]Wikipedia,Discounted cumulative gain.
[6]Wikipedia,Domain-driven design.
[7]Wikipedia,Elasticsearch.
[8]Wikipedia,k-d tree.
[9]百度百科,太陽歷.
[10]百度百科,陰歷.
[11]Xinran H, Junfeng P, Ou J, et al. Practical Lessons from Predicting Clicks on Ads at Facebook
[12]Olivier C, Donald M, Ya Z, Pierre G. Expected Reciprocal Rank for Graded Relevance
[13]Heng-Tze C, Levent K, et al. Wide & Deep Learning for Recommender Systems
文章版權(quán)歸作者所有,未經(jīng)允許請勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請注明本文地址:http://www.ezyhdfw.cn/yun/19880.html
摘要:一些知識點有哪些方法方法前端從入門菜鳥到實踐老司機所需要的資料與指南合集前端掘金前端從入門菜鳥到實踐老司機所需要的資料與指南合集歸屬于筆者的前端入門與最佳實踐。 工欲善其事必先利其器-前端實習簡歷篇 - 掘金 有幸認識很多在大廠工作的學長,在春招正式開始前為我提供很多內(nèi)部推薦的機會,非常感謝他們對我的幫助?,F(xiàn)在就要去北京了,對第一份正式的實習工作也充滿期待,也希望把自己遇到的一些問題和...
摘要:更多資源請文章轉(zhuǎn)自月份前端資源分享的作用數(shù)組元素隨機化排序算法實現(xiàn)學習筆記數(shù)組隨機排序個變態(tài)題解析上個變態(tài)題解析下中的數(shù)字前端開發(fā)筆記本過目不忘正則表達式聊一聊前端存儲那些事兒一鍵分享到各種寫給剛?cè)腴T的前端工程師的前后端交互指南物聯(lián)網(wǎng)世界的 更多資源請Star:https://github.com/maidishike... 文章轉(zhuǎn)自:https://github.com/jsfr...
摘要:技術(shù)之類加載機制掘金類加載機制是語言的一大亮點,使得類可以被動態(tài)加載到虛擬機中。玩轉(zhuǎn)仿探探卡片式滑動效果掘金講起本篇博客的歷史起源,估計有一段歷史了。 Java 技術(shù)之類加載機制 - Android - 掘金類加載機制是 Java 語言的一大亮點,使得 Java 類可以被動態(tài)加載到 Java 虛擬機中。 這次我們拋開術(shù)語和概念,從例子入手,由淺入深地講解 Java 的類加載機制。 本文...
閱讀 3159·2021-11-22 09:34
閱讀 657·2021-11-22 09:34
閱讀 2516·2021-10-08 10:18
閱讀 3444·2021-09-22 15:57
閱讀 2698·2021-09-22 15:25
閱讀 2503·2019-08-30 15:54
閱讀 2254·2019-08-30 15:44
閱讀 1854·2019-08-29 11:18