◆版權聲明:本文出自胖喵~的博客,轉載必須注明出處。
轉載請注明出處:https://www.cnblogs.com/by-dream/p/10450880.html
做推薦算法的質量工作將近一年,這一年嘗試了很多東西,踩了不少坑,也對推薦的評測工作稍微有了些自己的心得,現在分享出來,希望能和做這塊工作的同學一起交流、探討,也歡迎多拍磚,多提意見。
推薦系統
目前推薦技術的應用已經非常較普及了,新聞、商品、問答、音樂,幾乎都會用到推薦算法來為你呈現內容。下面是淘寶、知乎、微博三個app的推薦模型,可以看到推薦都在非常重要的位置。
在介紹推薦算法評測之前,我先簡單說下推薦系統,這里我以商品為例,簡單描述下推流程,讓大家更明白一些,一般推薦主要包含以下步驟:
召回->打分排序->透出
召回
召回階段通常的手段是協同過濾比較場景的i2i,u2i等這種x2x(有興趣可以看下我寫的基於itembase的推薦),也有使用embedding的方式通過向量之間的距離進行召回。以i2i為例,假如現在要針對我推薦一個商品,那么首先要找到我感興趣的物品 ,這些數據是通過我的歷史行為來進行獲取,比如拿到我最近一段時間內的點擊、加購、收藏、購買的物品,將這些商品做為trigger進行召回,協同算法的具體就不再這里敘述了,有興趣可以看下鏈接,最終我們按照協同過濾算法算出商品之間的相似分值,然后按照一定數量進行截斷,因為這里截斷也是依靠分數來進行的,所以一般這一步也稱粗排。這樣召回截斷就完成了。
打分
召回完商品后,我們需要對這些商品進行再一次的精排,這里需要用模型來預估ctr,一般情況下LR、GBDT、FM用的比較多,這里深度網絡相對用的少,主要為了考慮到性能,尤其是rt,因為絕大部分的精排都是需要實時預測的,所有對耗時有一定的要求。繼續說下模型預測的步驟,首先針對召回的商品進行特征的補充,例如該商品的一級類目、葉子類目(一級類目代表比較,葉子類目代表最細分的類目)、被多少用戶購買等,然后再加入人的特征,例如性別、年齡、收入、對類目的偏好等,然后將這些信息做為feature,用模型進行預測,然后根據模型預測的結果進行排序,輸出。
模型
打分過程中的模型是需要提前訓練和部署,訓練集的來源就是用戶的實時行為加上用戶和商品的特征。feature的構成是用戶的特征和商品的特征,label則是用戶是否點擊了該商品。
質量方案
接下來說下如何保證這塊的質量。由於推薦系統最終對用戶需要提供實時的服務化,因此免不了有工程端的技術需要一起配合。因此我這塊主要分為兩個維度來開展,一方面是工程端的質量保證,一方面是算法側的質量保證。
工程端質量
這一塊可以將算法當成一個黑盒子,只把他當成一個有結果返回的接口。針對這方面前人已經有了豐富的經驗,我們可以做接口的單元測試和冒煙測試,另外就是壓測,在預估的qps下看rt是否滿足業務方的要求,load是否過大,超時和錯誤的比例是否符合一定的預期。這里就不細說了,重點說說第二部分。
算法端質量
這里我再進行細分一下,分為三部分介紹:算法數據、算法模型、算法效果;
算法數據:
大家都知道算法在做訓練前數據的處理部分非常的重要,有興趣可以看下特征工程相關的內容,數據的來源,特征的構造,數據抽取、加工整個的過程都有可能會出現錯誤,而且數據一般都是存儲在分布式系統數據庫里,因此需要借助類似hive這樣的工具將sql轉換成MapReduce的任務去進行離線的計算,離線任務的產出通常會耗費不少的時間,而對於一些日更新的模型通過對數據對產出時間有一定的要求。因此數據這塊最主要的保證點為:數據本身的質量,和數據的產出時間。數據本身的質量一般可以通過數據大小的整體抖動,以及關鍵字段是否為空,主鍵是否重復,做法比較簡單可以通過簡單sql或者udf來完成,然后借助工程能力做到預警、檢查、出報表等。
算法模型:
模型的本身在迭代過程中也是需要關注的,不過通常算法同學的訓練優化也是參考這些指標,所以我們也可以把這幾個指標做為模型本身好壞的評估。具體為:准確率、召回率、AUC。
算法效果:
那么這個算法推薦出的效果究竟好不好呢,這個是一個非常主觀的事情,每個人的感受也不是一樣的,但是我們仍然要衡量它的好壞,這里我參考業內學者的推薦書籍以及自己的一些摸索,總結出下面一些方法,供大家參考。
人工評測:
顧名思義,邀請一幫人來對你的推薦系統的結果進行評測。這里想法來自於我在做翻譯評測時期的經驗,首先這個成本比較高,另外就是參雜了人的主觀性非常的高,翻譯的好壞我們可以通過制定一些細致的規則來進行約束,但是推薦的好壞我們卻不好制定詳細的規則,另外就是推薦之前的用戶行為如何模擬,如何讓評測者進行感知,這些都是比較難的,並且和基准的對比也不是很好做,所以這里不是很推薦用這個方法,但是還是要提一下。
指標評估:
指標化推薦結果,也就是將推薦的結果用不同的指標來進行說明,通過這些指標,你可以更加的了解你的推薦系統,部分指標不一定越高越好,但是你需要讓它保持在一定的范圍內。說到具體的例子的時候,我會提一下。下面我們看下這些指標。
覆蓋率
定義:
推薦系統能夠推薦出來的“商品/類目”占“總商品/類目”集合的比例。假設系統的用戶集合為U,推薦系統給每個用戶推薦一個長度為N的物品列表R(u) ,總物品為N。那么:
覆蓋率 = $\frac{\Sigma R(u)}{N}$
描述推薦結系統對物品長尾發掘能力;
舉個例子,淘寶上商品千千萬萬,推薦系統能否保證讓新的一些商品有足夠的機會曝光出去呢?還是有些商品永遠都無法得到推薦曝光的機會。這個指標反應的就是這個情況,顯然物品的覆蓋率是達不到100%的,但是我們可以看類目的覆蓋率來進行衡量,假設全網所有的一級大類目一共2千個(和全網上億的物品相比非常的少),那么推薦系統一天之內推薦出去的商品對應的一級類目,這個就是我們要衡量的標准。如果覆蓋率達不到100%,那么肯定是有問題的。
基尼系數
覆蓋率反應出的分布情況是比較有限的,我們只能知道哪些類目覆蓋了,哪些沒有覆蓋,那類目之間究竟哪個類目占的多,哪個類目占的少呢?為了更細致地描述推薦系統發掘長尾的能力,我們需要統計推薦列表中不同類目出現次數的分布,引入基尼系數來評價。
基尼系數:按照類目的流行度(曝光次數)從大到小排序后進行統計后進行洛倫茨曲線的繪制。
做法:
以類目分布基尼系數為例,算出所有的類目被曝光的次數,需要以天周期為單位進行數據的統計。
這里需要說明一下,基尼系數越大代表所有類目的分布越不均勻,系數越小代表類目分布越均勻。我們知道,每個電商網站都有其側重的類目,因此絕對平均不是一件好事,頭部的類目占比稍多一些但是不能太離譜,舉個例子100個類目,前5個占比到30~40%是相對比較好的。當然絕對的只看這個數據意義也不是很大,更多的是長期對這個指標進行監控,看是否會發生大的變動。
打散度
定義:描述推薦結果中結果數據的分散程度。
打散度 =
$\frac{2}{k(k-1)} \sum\limits_{i\neq j}^{k} 0.85^{dis((i,j)-1) * sim(i,j)} $ (dis(i,j) = |i-j|,sim(i,j) 為 i==j?1!0)
這里需要解釋一下,這里首先是對兩兩物品(不同的位置)計算為打散度后,得出整體的打散度。相似函數sim代表兩兩是否相同,相同則為1,不相似則為0。關於兩個內容之間距離對打散度的影響,不能是線性的關系,因為隨着兩個商品出現的位置越來越大,用戶對重復商品的感受會逐漸的減弱(很近的位置就有兩個相似的內容覺得會有些重復,但是如果比較遠的位置有兩個相似的一般是可以接受的),一般雙列流屏幕出現內容大概是4個,0.85^(5-1) 大概在 0.5左右,所以如果是5以內,則打散度會很低,但是如果>5了,打散度就不會衰減的比較厲害了。 相似的兩個物品越靠近,權重越大。
定義:描述推薦系統不斷迭代過程中推薦結果變化程度的指標。
更新率 = 1 - $\frac{S_{昨日} ∩ S_{昨日}}{S_{昨日} ∪ S_{昨日}}$
上面公式還是以類目為例,$S_{昨日}$代表昨天一天出現的所有商品所在的類目的個數,然后兩天的交集除以並集,計算得出推薦出商品所屬類目的更新率。
發現性
定義:推薦系統對用戶未產生過關系的商品的發現能力。
在全網商品中,可能有一些比較好的商品,但是用戶從來都沒有點擊過類似的物品,這時候推薦系統推薦給用戶的時候,用戶很有可能會眼前一亮,滿滿驚喜。
發現性 = $\frac{1}{n} \sum\limits_{i=1}^{n} \frac{ S_{今日點擊(前一周未點擊)} }{ S_{前一周點擊}}$
同樣以類目為例,今天我點擊了一個我感興趣的商品,而這個商品的類似恰恰是我前一周都沒有點擊過過的內容,這就說明推薦系統的為我推薦了一個我之前都沒有關注過並且我感興趣的內容,也就是系統的發現性,在算出每個人的值之后,再進行求平均計算。
上新率
定義: 新內容被推薦系統推薦的曝光情況,這里可以從兩個維度產出這項指標。
上新率1 = $\frac{當日曝光的內容中內容為最近一周生產的內容數}{當日曝光內容數} $
上新率2 = $\frac{當日曝光的內容中內容為最近一周生產的內容數}{最近一周生產的內容數} $
意義:對於一些社區類產品UGC內容的推薦,用戶生產的優質是整個社區最重要的一部分,及時的曝光用戶的新內容對於增加用戶留存和給社區增添活力都有很大的幫助,因此需要這兩個指標來評估推薦算法對於新內容的推薦能力。
NDCG
有些文章中也推薦使用這個指標,但是個人覺得這個更加適合評價搜索結果,之前寫過一篇關於NDCG的文章,有興趣可以看下。
失效率
定義: 表示系統沒有推薦或推薦后未被用戶點擊數據占全集的比例。
S(0) 表示實際點擊次數為 0 的數據個數;S表示推薦集合的總數。
首先需要定義一個時間范圍來計算沒有被推薦出的。其含義為最終未被用戶真正感知的數據的占比,未感知包含未推薦和推薦出去后未被點擊的內容。
健壯性
定義:算法健壯性的評測主要利用模擬攻擊。首先,給定一個數據集和一個算法,可以用這個算法給這個數據集中的用戶生成推薦列表。然后,用常用的攻擊方法向數據集中注入噪聲數據,然后利用算法在注入噪聲后的數據集上再次給用戶生成推薦列表。最后,通過比較攻擊前后推薦列表的相似度評測算法的健壯性。
總結:適合在離線環境進行完成,針對模型本身的評測。
除了上面介紹的通過這些指標的方法來進行評估,當推薦真正運用在業務上,通過業務側的一些數據反饋也可以知道推薦算法的好壞。具體看下面兩項:
負反饋
定義:負反饋相當於一個輕量級便攜的用戶反饋,用戶可以直接對推薦出的內容給與反饋,推薦系統在拿到了用戶實時反饋后就會立刻針對反饋信息對推薦結果做出相應的調整,而我們也可以在事后拿到負反饋的整體數據來評價推薦系統在用戶側是否有重大輿情產生。一般app的推薦都會有負反饋機制,如圖:
ctr
Click-Througt-Rate,即點擊率,點擊數/曝光數。推薦算法效果的最最重要指標,沒有之一。一般算法好不好,都會直接用這個指標直接定義。通常算法模型在迭代的過程中都會進行ab test,所謂ab test就是有一個基准桶,一個對比桶,通過收集兩個不同方案在用戶側的點擊率,來評估算法的好壞,一般來說當流量特別大的時候,基本上一個ab實驗上線幾分鍾就可以出算法的好壞了。當然算法的分桶不僅限只有兩個桶,像下面這個推薦每個分桶的數據都可以非常直觀的展示出來。一般需要借助像Blink這樣的實時計算能力來實時的顯示點擊率數據。
cvr
Conversation Rate,即轉化率,轉化數/點擊數。通常在廣告上用的比較多,對於商品來說也就是用戶最終點擊並且購買的轉化率。因為最終決定轉化的因素還是比較多的,不單單是推薦算法影響的,所以這個指標通常不做為模型迭代優化的衡量標准,但是由於其和最終的"錢"掛鈎,所以一般領導會更加關注這個指標。
總結
上面說了很多指標,其實單看指標可能沒有特別好的體感,更多的時候,我們需要真正的將這些內容結合到業務上去,看它究竟反應業務什么樣的情況,抽絲剝繭,更加的理解業務、反哺業務,任何一個指標都需要對業務有指導意義,真正幫助業務提升。最后,我將整體的質量方案也畫了一個概要圖,可以參考看看。