如何做好「推薦演算法」?有哪些常見的錯誤需要避免?


感謝邀請。

1.首先要定義好什麼叫」好的推薦「,這是解決任何一個技術問題的前提。

2.在有了明確的定義之後,實際問題一般會蛻變為一個優化問題,用數學工具給出它最好的解答。

3.數學上的解答可能在技術上無法實現,或者說有可能複雜度太高,那麼需要一個比較好的近似解。不要小看這一步,大部分問題出在這裡。

4.迭代改進。演算法實現以後可能實際表現與預想的不同,需要重新定義」好的推薦「。這樣一個周期下來,推薦效果應當有肉眼可見的改進。

不光是推薦演算法,任何一個技術問題都是這樣。


金角大王將寶葫蘆倒置,喊聲:孫行者。悟空應了一聲,嗖地便被吸了進去。金角大王查看時,裡面除了孫悟空,還有行者武松、蒼井空、孫權、六耳獼猴、金剛等一干人。 金角大王驚訝道:只喊孫行者,怎來了這許多。寶葫蘆開口言道:這都是你「可能感興趣的人」。


這個暑假在Bloomberg實習做的就是有關推薦演算法,來答一下。僅僅是三個月的理解和積累所以會有錯誤和不全面的地方,歡迎多多交流!

推薦演算法最傳統的有兩類,content-based和collaborative filtering.

1. content based(就簡稱他CB):

content based, 顧名思義,就是主要考慮一個商品固有的內在屬性。對於每個商品item, 需要建立item的profile.對於每個用戶,要建立user profile. 舉個例子,你在知乎上搜索過編程,搜索過美食,那麼你的user profile就會顯示你是對編程,美食感興趣的。那麼假如我們把item profile簡單的看成每個問題的tags的話,那麼有編程,或者美食的標籤的問題你很可能感興趣。

CB做的最好的是Pandora, 他們最有名的music genome project是人工標記一首歌曲的profile

2. collaborative filtering(cf):

cf的精髓是在於他用「和用戶x相似的用戶的購買習慣推測x想要購買的東西。細分的話cf演算法有user-based和item-based. user-based可以這樣解釋:想要知道我對」有一雙美腿是什麼體驗「這個問題的喜好程度,通過對比我的和其他人的閱讀記錄,發現我和另外100個知乎用戶很像,都讀了很多編程和美食方面的問題。而這中間99個人都讀了」有一雙美腿是什麼體驗「,還在上面停留了很久,尤其是有圖的回答。。。那麼因此可以推斷我也會喜歡這個問題。cf最難的問題在於怎麼尋找」最相似的用戶「。在machine learning里這個就是k nearest neighbor. 我嘗試的演算法叫locality sensitive hashing with minhashing. 不知道還有什麼別的方法。

CF的話比如amazon, 你會經常看到user who bought this also bought that...

問題:

可是問題又來了,如果仔細想一下就知道剛才cf做的事情不太對。為什麼呢,因為幾乎所有知乎用戶都愛讀有一雙美腿是什麼體驗,愛看圖,這個東西不是愛美食的程序員這些人特有的,所以我雖然很可能感興趣,但是並不是因為cf的功勞,而是這個問題本身就很受歡迎。這在推薦演算法中叫做banana problem.原因是在美國這邊的超市,幾乎所有人都愛買banana,因為最便宜,也好吃也健康。所以過多的數據量可能會導致一個超市推薦演算法瘋狂推薦Banana給所有人。這是一個需要解決的問題,比如推薦大家都愛看的經典電影可能沒錯,但是推薦香蕉給來超市的,推薦口香糖給一個一周買五次口香糖的可能就沒什麼用。

3.matrix factorization

幾年以前netflix有過這樣一個競賽,誰的推薦演算法比他的牛逼10%,就能拿走一大筆獎金,好像是100w美金。這個競賽中風靡著這樣一種矩陣分解的演算法。(2012年的數據,netflix 75%的觀看量是從推薦引擎里來的,這也就是為什麼他們那麼注重推薦演算法)

我們想像這樣一個矩陣M,每一行代表一個用戶,每一列代表一個電影。那麼M[i][j]就是用戶i對電影j的評分。可能存在,也可能不存在(如果i沒看過j的話)。假設有m個用戶,n個電影,那麼這個矩陣就是m*n矩陣。現在,我們要把它分解成(m*f) * (f*n)的兩個矩陣之積。(f 是電影feature的個數)第一個叫user matrix, 第二個叫item matrix. 那麼user matrix 每一行代表的是什麼呢:是用戶對於每個feature分別的喜歡程度。比如我們定義features為&<喜劇,恐怖,武打&>, 那麼用戶u在user matrix的那一行可能是&<1.0, 0.2, -0.2&>,這說明了u最喜歡喜劇,討厭恐怖,更討厭武打。那麼在item matrix里,每一個電影又對應了他們」所含「各個feature的程度。比如煎餅俠可能是&<1.0, 0, 0.2&>, 某個恐怖片可能是&<0, 1, 0.5&>. 那麼我們算這兩個向量的點積的話,分別得到M[u][煎餅俠] = 1-0.04 = 0.96 M[u][恐怖片] = 0.2-0.1=0.1. 那麼這樣u肯定就會更喜歡煎餅俠啦!這個方法Simon Funk這個人的演算法最快。可以搜一下。還可以給他本人發郵件。。。這個方法最頭疼的就是M里有用的太少,比如一個人一輩子就點評過一個電影,那怎麼推薦嘛。。。這種情況就要用我們的content-based了,因為其他的任何演算法都是建立在我們有足夠的user interaction的前提下的。


一個好的推薦系統,其實需要產品和演算法的共同作用。

好的做事的方法論應該是

1.產品描述和定義目標結果集

很多不懂演算法的產品會在這上犯錯,將提升產品效果全部推給距離業務相對較遠的演算法人員,而且只會要求所謂精準,這其實是不懂+不負責任的表現

產品需要深入理解某個推薦系統中,用戶實際的需求內容是什麼,什麼樣用戶喜歡發散的,什麼樣用戶喜歡集中的,什麼樣用戶喜歡熱門的。還是用戶行為基本無差異?如果你是簡單的推薦item讓用戶去點擊,那麼影響點擊的這些item的特徵到底是什麼,漂亮的圖標?具有特殊風格的summary介紹文案?吻合用戶個性化的過往的使用記錄?是用戶的好友使用過的並評價良好的?還是隨便什麼內容放上去就有點擊,推薦系統在此用不上?

如果PM對用戶需求和item特質建立不了系統化結構化的模型,對用戶使用行為的背後動機沒有深入的思考,基本上是做不出好的推薦系統的,起跑線上就輸了。

光會逼逼叨 精準 啊, 好 啊這種模糊且近似廢話的形容詞也沒什麼用。

2.共同理解推薦系統的實現方式

光有第一條還不足以落地,第一條更多的時候是定性的描述,或粗淺的定量(比如什麼大於什麼),離實際落地的效果還很有距離。這時候懂演算法的工程師需要出馬。

我覺得演算法可以拆成兩種,一種是規則或策略,一種是機器學習的複雜演算法

對於頭一種,需要產品和演算法對規則的共同理解。比如我想要一個總贊成票和反對票的關係,那麼是贊成票-反對票好,還是贊成票/反對票好,還是log(贊成票/反對票)好,還是贊成票/(反對票+c)好,這裡面其實差異還是不小的,演算法工程師可以幫產品多考慮極端的數值情況,將模糊的規則描述為精確的可計算的數學模型。好的模型應該兼具效果和解釋性,工業環境下有個很重要需求就是老闆們發現一個case,你至少能解釋的通是模型問題還是數據問題吧

對於第二種,由於實際運行起來解釋性很差,個人建議用來做最低層最通用的一些處理就好,然後通過大量的case評測來對效果進行評估。比如把SVM構造成文本分類器之類。

總之就是機器學習演算法作為底層和通用的模塊向下沉降,上方用大家都可理解的簡單規則根據場景不同靈活調配。

3.實際線上推薦效果的檢驗

一切事前的驗證都不如事後驗證來的靠譜。

對於短期和立即見效的case,記得流量要切的均勻,且保持單一變數(改動)原則

對於長期才能見效的case...說服老闆給足夠多的時間來等

對於數據變化不明顯的case,要麼作為一個體驗改進,當做良心活做,要麼就通過bad case率來給效果做檢測。

4.對實際運行結果的解讀及從中找到改進點

這個太case by case了。不過我比較認可的理念是:運行結果代表對上一次拍腦袋行為的肯定或打臉,通過運行結果你沒法直接得到一定能有效果的改進。改進仍然是一種類似感性的拍腦袋的驅動方式,我們就是不斷的拍腦袋,然後不斷的檢測拍腦袋的成果。好的決策是用數據沒法先驗得出的。

5.跳出思維局限,找到大創新

以上4個是我認為好的工作流程。但是是對一般系統的改進來說的,很多時候我們要解放推薦。比如,放相關歌曲是推薦,豆瓣電台也是推薦,把所有歌手跑成一張地圖讓用戶模糊的去選擇也可以是一種推薦,演算法的力量,也許換一種產品形態,就會有飛躍的改進。這是你微調大半天也不一定搞得出來的。

PS.知乎的排序規則有些地方不夠好,我猜知乎可能沒有對用戶在某一領域的權威度進行建模。所以在之前討論」專業和業餘「的問題時,有人說答一個自己業餘的問題得票比自己專業問題還火的情況。而且目前越早回答的問題得票越有優勢。這些都是問題,都需要改


1.關於如何做好

1.1宏觀: 做好推薦演算法必須以產品做為導向(見圖一),並輔之以全局思維(整體優化),從設計方案、數據收集、架構到落地應用

1.2微觀: 挖數據/洗數據/分析數據/合適的特徵+根據產品/數據形態選合適的演算法+根據評估指標調優(調參),中間是不斷的嘗試

2.常見錯誤:舉了幾個例子,見圖二、三(我的知乎live中ppt的截取)

有興趣的歡迎關注我的live 推薦演算法那點事》:知乎 Live - 全新的實時問答

圖 一

圖 二

圖 三


我建議還是看看這三篇文章會有很大的幫助。

探索推薦引擎內部的秘密,第 1 部分: 推薦引擎初探

探索推薦引擎內部的秘密,第 2 部分: 深入推薦引擎相關演算法

探索推薦引擎內部的秘密,第 3 部分: 深入推薦引擎相關演算法

目前的推薦演算法主要還是基於人(user)或者內容(item)來進行建模,所以常用的演算法也基於人或者內容,還有一種採用降維的混合式演算法也比較有效,推薦演算法個人認為現階段要達到非常靠譜的效果還是很難的,基於已有數據做推薦容易形成小圈子,很難從一個知識結構中跳出來。


有一個問題,人為什麼需要推薦?什麼場景下需要推薦?不同場景下的推薦要注意什麼事項?


簡單說下我覺得實際應用時可能需要考慮的方面。

數據:不同的數據適應不同的演算法。例如只有用戶的行為數據(例如購買、查看等交互數據),則只能選用簡單的演算法(例如協同過濾,基於物質擴散的演算法等),如果包含用戶或物品信息,可以選用較為複雜的演算法。一般來說,使用的信息越多,得到的結果越精準。

產品類型:每個推薦系統所針對的產品不同(例如買商品的和推薦電影的),所選用的演算法也應該是不盡相同的,盡量利用所在產品系統自身的特點。

冷啟動 :在推薦演算法啟動初期的數據是否夠,對新用戶和新產品是否也能進行推薦。

性能:是否需要實時推薦。非實時推薦對性能的要求比較低,則可以選用較複雜的演算法。實時推薦則對性能要求比較高,一般選擇複雜度較低的演算法。

多樣性:精度和多樣性的問題。在精度達到要求的情況下可以考慮推薦的多樣性。


最常見也最應該避免的錯誤就是不問清楚推薦目標和場景就是開始聊數據在哪裡打算怎麼做。這是大多數產品經理提需求時的通病。不聊他為什麼這麼做,直接說我要這個東西,老闆說很重要,你什麼時候能做完?而業務型演算法團隊會在各種威逼利誘下妥協,做了一個個莫名其妙又不了了之的演算法產品。什麼數據坑,什麼埋點坑也都是一個個不慎重的需求帶來的。


結合58招聘推薦的場景,基於長期的業務實踐,寫了一篇《分散式離線加實時增量更新的協同過濾演算法》,希望能和大家一起學習交流。其中文中的介紹了如何做推薦演算法選型、如何分散式實現、如何實現實時的增量更新等實踐中遇到的問題,可供查考。

該文的組織邏輯如下:

首先,簡單介紹58趕集招聘業務線現在的推薦系統現狀;

然後,詳細講述本文基於招聘推薦場景實現的離線加實時的Item based CF演算法分散式設計與實現;

其次,給出了實際線上AB實驗的推薦效果分析;

最後,簡述了該演算法的未來可優化點 。


可以參考下一個實際項目總結:

電商行業智能推薦引擎的探索——機器學習助力母嬰電商

原文鏈接:電商行業智能推薦引擎的探索

業務挑戰

隨著電商網站用戶數量和商品數量的增加,數據成為影響推薦質量的重要因素。作為電子商務中一個熱門領域,價值萬億的中國母嬰市場隨著二孩政策的全面放開已經進入高增速增長時代,母嬰消費市場每年可新增超300億母嬰消費,至少帶來年均13%左右的新增長空間,巨大的市場必然蘊含著巨大的商機和強大的利潤空間。

眾所周知,解決信息過載的方式主要有類目導航、搜索、推薦,還有目前大熱的聊天機器人(chatbot),但其本質也是基於推薦系統和知識圖譜實現的。推薦不同於或者優於搜索的地方在於:搜索需要用戶知道自己需要什麼,而推薦則可以做到幫助用戶發現自己需要什麼或者讓你需要的信息主動找到你,而且更加個性化,甚至能做到「比你自己更了解你自己」。

傳統推薦機制主要有基於人口統計學的推薦機制的工作原理和基於內容推薦機制的基本原理。

基於人口統計學的推薦機制的工作原理

豆瓣的推薦「豆瓣猜」

基於內容推薦機制的基本原理

而母嬰類的商品具有種類多、功能相似的特點,用戶在購買時會出現「信息迷航」的問題,同時,由於母嬰市場激烈的競爭,商品同質化越來越嚴重,傳統的推薦機制能難滿足業務需求。

對於本次合作而言,所面臨的主要挑戰就是如何設計智能推薦引擎從海量商品中準確找到用戶所需要的商品。

混合IBCF演算法的離線與實時的分散式設計實現

在現行的 Web 站點上的推薦往往都不是單純只採用了某一種推薦的機制和策略,往往是將多個方法混合在一起,從而達到更好的推薦效果。結合業務痛點,我們採用一種基於矩陣填充技術的混合IBCF演算法。首先利用準確度指標找出SVD的最優參數和混合IBCF演算法的最佳權重,然後使用SVD降維方法對原始的高維稀疏矩陣進行預測填充,最後使用IBCF在用戶所屬類中尋找目標用戶最近鄰並使用最佳權重合併結果產生推薦。該演算法利用用戶與商品之間的潛在關係克服了稀疏性問題,同時保留了可離線建模、可擴展性好等優點。

以母嬰產品為例,通過分析母嬰類產品,收集數據集構造母嬰領域不同類型產品的特徵向量。提取母嬰類偏好係數不為0的用戶為目標用戶,通過用戶訪問的時間偏好來確定服務推薦的權重,計算其訪問的母嬰類與目標產品的特徵向量的相似度來確定推薦產品的類型。最後,在母嬰之家購物平台上實踐結果表明,該方法確實可提升用戶的個性化推薦。

用戶個性化需求解決方案設計

提高計算精度——優化k值,SVD和ItemCF的合併

由於母嬰類商品的相似性較高,不同商品具有比較固定的相似度,所以我們使用基於物品的協同過濾演算法(IBCF)來進行推薦,在推薦過程中可以預先在線下計算好不同商品之間的相似度結果,然後把結果存在相似度表中,當推薦時進行表的查詢,預測用戶可能的偏好值,從而進行推薦。同時,由於母嬰商品相似度高,當推薦過程的運算量比較大的時候,使用物品的一個小部分子集也可以得到高質量的預測結果。

針對上述問題,使用SVD方法將用戶評分分解為不同的特徵及這些特徵對應的重要程度,利用用戶與商品之間潛在的關係,用初始評分矩陣的奇異值分解去抽取一些本質的特徵,降低數據維度來進行推薦,從而提高運算效率。

由於SVD演算法中保留的維數k很重要,也不容易選取,k如果太小,容易失去原始數據中重要的信息,不能得到用戶評分矩陣的重要結構,k如果選大了,達不到降維的目的,而且容易過擬合訓練數據,因此測試數據時需要先對k的取值進行優化,選取最優的k值然後再進行實驗。

更客觀地評價用戶對商品的興趣——用戶行為權重、用戶遺忘曲線

首先根據用戶的不同行為(bhv)定義偏好權重,行為: "投訴" 、"下單"、 "商品瀏覽" 、"商品加入購物車" 、"評論"分別對應偏好分值-1、4、3、2、3。

然而傳統的推薦基於用戶興趣是固定不變的假設,即用戶興趣不隨時間的變化而改變,因此,這些方法不能反映用戶興趣的變化。同時,被推薦的資源(產品)往往具有時效性,用戶的興趣也往往隨時間的不同而變化。

針對以上問題,為了滿足用戶的個性化需求,我們提出了基於時間加權的協同過濾演算法,考慮了時間對推薦質量的影響,認為用戶興趣隨時間的流逝而衰減,即某個用戶感興趣的資源最可能和他近期訪問過的資源相似。

其中,艾賓浩斯遺忘曲線可以較好的描述用戶瀏覽商品和遺忘的過程。它認為當用戶瀏覽商品時,商品信息輸入大腦後,遺忘也就隨之開始了。遺忘率隨時間的流逝而先快後慢,特別是在剛剛識記的短時間裡,遺忘最快。遵循艾賓浩斯遺忘曲線所揭示的記憶規律,對所瀏覽的商品及時進行推薦,可以提升用戶的個性化推薦。

因此,我們根據用戶對商品行為距今的時間差對用戶的偏好進行權重調整,其中時間權重的計算使用艾賓浩斯(H.Ebbinghaus)遺忘率 ,得到最終的用戶行為偏好為。

用戶購買周期性問題解決——懲罰上一周購買

然而,常常存在這樣一種現象,用戶往往在根據自己的興趣愛好購買了商品之後,一段時間內會對所購買物品相似的物品產生「疲倦期」,會更加趨向於選擇與以前購買過的商品較為相異的那些新商品進行購買。從本質上講,這種情況往往發生在作為用戶短期興趣的資源上,這樣的用戶興趣會隨時間的接近而衰減。因此,如果能有效識別出用戶的短期興趣,在預測用戶最感興趣的資源時加以考慮,區分不同時間對推薦的不同影響,可以提升用戶的個性化推薦。

因此,進一步清晰區分用戶長期興趣和短期興趣在預測評分時所起的不同作用。認為預測資源的評分時,作為短期興趣的可進行衰減。


因為,人們用同類人的選擇結果,作為自己的決策參考,有前車之鑒的意義,所以人們需要推薦。

當人們面臨選擇時、決策時,需要推薦中肯的意見。面臨不能確定的問題時,需要推薦別人的結果。

不同場景對於不同用戶的識別值得注意。對於不同用戶訪問路徑值得注意。

不知是否能幫到你。。。


噗。。。其實有一段時間再做軟體的推薦方法,做的時候最糾結的就是每個人點開一個app的時候他的需求點都是不同的,所以會有很多歧義,現在覺得還是沒有做得很讓人滿意,不過其中有幾個點可以分享一下:

1 怎麼為每個應用確定標示符,以及為每個應用貼上標示符的時候順序是否重要,後面這個問題其實也就涉及到你後面的演算法是否要把標識符的順序考慮進去了,因為每個人點開app時被吸引的點都不一樣,有的人是因為app的玩法,有的人是因為app的主角,有的人是喜歡app的風格,所以最後確定的是如果app是遊戲的話就根據:玩法,特色【比如是3D的?實景的?】,主角的順序來為給個app打上標示符

2 根據自己用戶的特點,把握大的方向,因為app store的應用各種各樣奇異功能的都有,而且類型也會越來越多,所以持續的維護更新標識符是一個一直要做的工作,但是確定第一批的時候可以現抓大的,比如遊戲的話:空戰,酷跑,賽車,射擊,塔防等幾個大類基本上可以涵蓋了遊戲的80%以上,所以大的類別一定要保證全部覆蓋,小的可以慢慢補充

3 考慮不同標識符的優先順序以及在結果中所佔的比例,比如你為一個應用貼上了4個標示符,他們之間的優先順序是怎麼樣的?是按照順序一個一個的匹配,還是都全部匹配但是不同的標示符在結果所佔的比例不同

4 其他維度的考慮,主要還是根據你的產品特性來定,對於app的話,比如根據你前期的匹配已經為用戶挑出了一批相應的應用,是直接就展示給用戶了還是再進行下一步的處理,要不要加入時間的考慮,只推薦近期熱門的,要不要加入價格的考慮,推薦出的應用裡面是不是應該把收費的控制在一定的比例等等

5 還有就是候補的方法,當有一個應用的標識符沒有足夠的應用跟他相匹配的時候怎麼辦?是根據名字的重合度推薦?還是取跟他同分類的熱門應用

其實覺得自己現在產品的推薦方法還是有很多可以改進的地方,坐等看大神的答案~~嗷嗚~~~


推薦閱讀:

請問隨機森林為什麼不會過度擬合?
有沒有機器學習方面集大成的教材推薦?
枚舉和窮儘是不是最有效,最暴力的演算法?
哪本《數據結構與演算法》最好?
機器學習演算法庫推薦?

TAG:演算法 | 推薦演算法 |