推荐系统杂谈
推薦系統(tǒng)是近些年非常火的技術(shù),不管是電商類軟件還是新聞類app,都號稱有精準(zhǔn)的推薦系統(tǒng)能給你推送你最感興趣的內(nèi)容。現(xiàn)象級的資訊類app“今日頭條”就得益于此成為了勢頭非常猛的一款產(chǎn)品。本文就針對推薦系統(tǒng)講述一些相關(guān)概念和實踐經(jīng)驗。
首先需要明確的就是推薦系統(tǒng)的目標(biāo),一般來說不外乎以下幾個:
- 用戶滿意性:首當(dāng)其沖的,推薦系統(tǒng)主要就是為了滿足用戶的需求,因此準(zhǔn)確率是評判一個推薦系統(tǒng)好壞的最關(guān)鍵指標(biāo)。
- 多樣性:雖然推薦系統(tǒng)最主要還是滿足用戶的興趣,但是也要兼顧內(nèi)容的多樣性,對于權(quán)重不同的興趣都要做到兼顧。
- 新穎性:用戶看到的內(nèi)容是那些他們之前沒有聽說過的物品。簡單的做法就是在推薦列表去掉用戶之前有過行為的那些內(nèi)容。
- 驚喜度:和新穎性類似,但新穎性只是用戶沒看到過的但是確實是和他行為是相關(guān)的,而驚喜度是用戶既沒有看過和他之前的行為也不相關(guān),但用戶看到后的確是喜歡的。
- 實時性:推薦系統(tǒng)要根據(jù)用戶的上下文來實時更新推薦內(nèi)容,用戶的興趣也是隨著時間而改變的,需要實時更新。
- 推薦透明度:對于用戶看到的最終結(jié)果,要讓用戶知道推薦此內(nèi)容的原因。比如,“買過這本書的人同時也買過”、”你購買過的xx和此商品類似”。
- 覆蓋率:挖掘長尾內(nèi)容也是推薦系統(tǒng)很重要的目標(biāo)。因此,推薦的內(nèi)容覆蓋到的內(nèi)容越多越好。
基于這些目標(biāo),推薦系統(tǒng)包括四種推薦方式:
- 熱門推薦:就是熱門排行榜的概念。這種推薦方式不僅僅在IT系統(tǒng),在平常的生活中也是處處存在的。這應(yīng)該是效果最好的一種推薦方式,畢竟熱門推薦的物品都是位于曝光量比較高的位置的。
- 人工推薦:人工干預(yù)的推薦內(nèi)容。相比于依賴熱門和算法來進(jìn)行推薦。一些熱點時事如世界杯、nba總決賽等就需要人工加入推薦列表。另一方面,熱點新聞帶來的推薦效果也是很高的。
- 相關(guān)推薦:相關(guān)推薦有點類似于關(guān)聯(lián)規(guī)則的個性化推薦,就是在你閱讀一個內(nèi)容的時候,會提示你閱讀與此相關(guān)的內(nèi)容。
- 個性化推薦:基于用戶的歷史行為做出的內(nèi)容推薦。也是本文主要講述的內(nèi)容。
其中,前三者是和機(jī)器學(xué)習(xí)沒有任何關(guān)系的,但卻是推薦效果最好的三種方式。一般說來,這部分內(nèi)容應(yīng)該占到總的推薦內(nèi)容的80%左右,另外20%則是對長尾內(nèi)容的個性化推薦。
個性化推薦系統(tǒng)
個性化推薦是機(jī)器學(xué)習(xí)應(yīng)用的一個典型場景。在本質(zhì)上和搜索引擎是一樣的,同樣是為了解決信息過載的問題。搜索引擎某種意義上也是一個個性化推薦系統(tǒng),但是其輸入特征是可以從搜索關(guān)鍵字直接可以得到的。而一般的推薦系統(tǒng),輸入特征則是需要機(jī)器學(xué)習(xí)才能得到。
個性化推薦系統(tǒng)一般由日志系統(tǒng)、推薦算法、內(nèi)容展示UI三部分組成。
- 日志系統(tǒng):這是推薦系統(tǒng)的輸入源,是一個推薦系統(tǒng)所有信息的源頭。
- 推薦算法:這是推薦系統(tǒng)的核心,根據(jù)輸入數(shù)據(jù)得出最終的推薦結(jié)果的具體過程就在這里。
- 內(nèi)容展示UI:對于推薦結(jié)果如何展示,也是一個值得權(quán)衡的地方。以更好地滿足推薦系統(tǒng)的目標(biāo),并能更好的收集用戶的行為信息等。
其中,個性化推薦中最為核心的推薦算法,目前比較流行的有以下幾種:
- 基于內(nèi)容的推薦:根據(jù)內(nèi)容本身的屬性(特征向量)所作的推薦。
- 基于關(guān)聯(lián)規(guī)則的推薦:“啤酒與尿布”的方式,是一種動態(tài)的推薦,能夠?qū)崟r對用戶的行為作出推薦。是基于物品之間的特征關(guān)聯(lián)性所做的推薦,在某種情況下會退化為物品協(xié)同過濾推薦。
- 協(xié)同過濾推薦:與基于關(guān)聯(lián)規(guī)則的推薦相比是一種靜態(tài)方式的推薦,是根據(jù)用戶已有的歷史行為作分析的基礎(chǔ)上做的推薦。可分為物品協(xié)同過濾、用戶協(xié)同過濾、基于模型的協(xié)同過濾。其中,基于模型的協(xié)同又可以分為以下幾種類型:基于距離的協(xié)同過濾;基于矩陣分解的協(xié)同過濾,即Latent Factor Model(SVD);基于圖模型協(xié)同,即Graph,也叫社會網(wǎng)絡(luò)圖模型。
個性化推薦系統(tǒng)的典型架構(gòu)如下圖所示:
在線業(yè)務(wù)系統(tǒng)的日志接入數(shù)據(jù)高速公路,再由數(shù)據(jù)高速公路迅速運轉(zhuǎn)到離線數(shù)據(jù)處理平臺和在線流計算平臺;離線數(shù)據(jù)處理平臺周期性地以批處理方式加工過去一段時間的數(shù)據(jù),得到人群標(biāo)簽和其他模型參數(shù),存放在高速緩存中,供在線業(yè)務(wù)系統(tǒng)使用,與此同時,在線流計算平臺實時對線上的日志數(shù)據(jù)做處理,對離線計算出的數(shù)據(jù)進(jìn)行補(bǔ)充、修正等;在線業(yè)務(wù)系統(tǒng)綜合離線特征和在線特征使用一定的邏輯得到輸出供業(yè)務(wù)使用,產(chǎn)生的日志流入數(shù)據(jù)高速公路。
基于此框架,個性化推薦系統(tǒng)的典型流程如下所示:
可知,一個推薦系統(tǒng)主要有以下模塊組成:
- 用戶行為日志:此部分主要是用戶行為日志的存儲,屬于數(shù)據(jù)統(tǒng)計的一部分, 存儲在hive中。在此不做贅述。
- 數(shù)據(jù)ETL-1:將用戶日志轉(zhuǎn)換為推薦算法所需要的數(shù)據(jù)格式。
- 推薦算法:是個性化推薦最主要的部分,包括通過用戶行為計算相關(guān)內(nèi)容以及推薦結(jié)果等。
- 數(shù)據(jù)ETL-2: 將推薦算法得到的結(jié)果進(jìn)一步加工為存儲模塊的輸入數(shù)據(jù)。
- 用戶畫像存儲:存儲用戶的偏好以及行為數(shù)據(jù),如對內(nèi)容關(guān)鍵字的偏好、點擊過哪些內(nèi)容等。
- 推薦結(jié)果存儲:存儲各種推薦算法產(chǎn)生的推薦結(jié)果,可以分為兩部分:{用戶 : itemList}推薦結(jié)果,為用戶推薦的內(nèi)容列表;{item : itemList}推薦結(jié)果,與item相關(guān)的內(nèi)容列表。
- 服務(wù)調(diào)用模塊:整合推薦結(jié)構(gòu),對外提供提供推薦的調(diào)用接口。
數(shù)據(jù)ETL-1
對原始的用戶行為等數(shù)據(jù)進(jìn)行清洗、加工,如字段、屬性、格式化等,作為下一步推薦算法的輸入。
推薦算法
對于個性化推薦系統(tǒng)來說,推薦算法應(yīng)該是其最核心的部分。目前有很多流行的算法,比如:
- 基于內(nèi)容和用戶畫像的推薦:此種算法,可見之前的一篇文章:http://www.rowkey.me/blog/2016/04/07/up-recommend/。
- 基于矩陣分解的推薦: 基于SVD/ALS算法對用戶進(jìn)行內(nèi)容推薦。相比起SVD,ALS更加適合解決稀疏矩陣的問題。Spark mlib中已經(jīng)集成了對als算法的實現(xiàn),需要做的就是在etl-1中把數(shù)據(jù)轉(zhuǎn)換為als需要的數(shù)據(jù)格式以及調(diào)整als算法的各種參數(shù)。這里有一篇文章比較具體地描述了如何使用spark來做基于ALS的推薦:http://colobu.com/2015/11/30/movie-recommendation-for-douban-users-by-spark-mllib/。
- 用戶&物品協(xié)同過濾推薦:包括UserBased CF和ItemBased CF。對于這兩者,需要根據(jù)業(yè)務(wù)的不同來選擇不同的算法。當(dāng)用戶非常多的時候,考慮到維護(hù)用戶矩陣的成本,一般是不推薦選擇用戶協(xié)同過濾的,而對于候選item很多的時候,則不推薦使用物品協(xié)同過濾。
推薦算法的輸出結(jié)果一般是一個用戶對應(yīng)一個item列表或者是一個item對應(yīng)一個item列表。此部分主要考慮的是算法的時間復(fù)雜度,不管是哪一種算法,一旦用戶或者內(nèi)容數(shù)據(jù)上了百萬級別,都需要通過分布式計算如MapReduce、Spark等來進(jìn)行解決。
推薦算法的基本流程如下圖所示:
數(shù)據(jù)ETL-2
對推薦算法產(chǎn)生的結(jié)果進(jìn)行清洗、格式化等,作為下一步存儲模塊的輸入。
用戶畫像存儲
存儲用戶的偏好以及行為數(shù)據(jù)等信息。對于偏好,采用標(biāo)簽量化來表示,是一種隨著時間衰減的值。對于用戶畫像,是批量寫入、實時讀取,所以存儲要著重考慮讀的性能。可以選擇使用Redis集群作為技術(shù)方案,能夠最大滿足讀的性能,缺點是Redis的成本昂貴且不支持auto index。也可使用Hbase作為存儲,使用ElasricSearch構(gòu)建二級索引,以應(yīng)對根據(jù)多種維度聚集用戶的需求(比如過濾某一個標(biāo)簽下的所有用戶)。
推薦結(jié)果存儲
對各種推薦算法計算出的推薦結(jié)果的存儲。存儲空間要求大,格式復(fù)雜。對于存儲的容量和讀寫性能要求都比較高。可以選擇使用Redis集群作為此部分的存儲方案。
服務(wù)調(diào)用
整合用戶畫像和推薦結(jié)果兩部分?jǐn)?shù)據(jù),向外提供推薦調(diào)用的接口。主要是數(shù)據(jù)庫IO調(diào)用開銷。
該模塊需要采取一定的策略聚合多種推薦算法的推薦結(jié)果,直接面向業(yè)務(wù)。策略由于會隨著面向的業(yè)務(wù)不同而不同,需要可配置化。同時也提供對外暴露用戶畫像的接口,使得業(yè)務(wù)方可以使用用戶畫像做針對性的處理。可以采用RPC機(jī)制對外暴露服務(wù)接口。
需要考慮的問題
對于一個推薦系統(tǒng),結(jié)合其實現(xiàn)目標(biāo),還有一些需要注重考慮的問題。
實時性問題
由于計算用戶、item矩陣或者進(jìn)行矩陣分解是需要離線進(jìn)行且比較耗時,因此協(xié)同的推薦算法是很難達(dá)到實時性的。實時部分的推薦主要依靠基于用戶畫像的推薦來進(jìn)行。最終的推薦列表是根據(jù)一定的策略對這兩部分進(jìn)行聚合的結(jié)果。
時效性內(nèi)容問題
時效性內(nèi)容指的是那些與時間強(qiáng)相關(guān)的內(nèi)容,比如新聞、時事等。如果一條10天前xx球員獲得冠軍的新聞現(xiàn)在被推薦了出來,可想用戶肯定是莫名其妙或者是很失望的。因此,對于時效性內(nèi)容,需要與普通的待推薦的內(nèi)容區(qū)分開,做單獨的推薦或者不走個性化推薦。
冷啟動問題
不管使用何種推薦算法,都會面臨冷啟動問題:當(dāng)用戶是新用戶,如何給用戶推薦item呢?當(dāng)內(nèi)容是新內(nèi)容,如何推薦給用戶?
- 對于新用戶,可以采取的一種策略就是采用熱門推薦或者人工推薦,把絕大多人關(guān)心的內(nèi)容推薦出來。
- 對于內(nèi)容,可以將內(nèi)容分為新內(nèi)容池和待推薦內(nèi)容池。新內(nèi)容產(chǎn)生時,首先進(jìn)入新內(nèi)容池。每次推薦的時候,先從新內(nèi)容池做候選推薦,并給此內(nèi)容的傳播度+1,直到其傳播度大于一個閾值的時候,將其移至待推薦內(nèi)容池。這樣既可以解決新內(nèi)容的冷啟動問題也在一定程度上可以保證新內(nèi)容的曝光量。
多樣性問題
在基于用戶畫像的推薦算法中,取出用戶的多個標(biāo)簽,然后根據(jù)相關(guān)度從不同的標(biāo)簽中取不同數(shù)量的內(nèi)容,這樣既兼顧了用戶的多種興趣也能夠在一定程度上解決多樣性的問題。
如:用戶具有tag:A B C D,相關(guān)度為wA wB wC wD,Total推薦為總共需要推薦的條數(shù),那么
RecommendList(u) = A[Total推薦 * wA] + B[Total推薦 * wB] + C[Total推薦 * wC] + D[Total推薦 * wD]內(nèi)容質(zhì)量
不管是熱門推薦、人工推薦還是取某一標(biāo)簽下的內(nèi)容列表都牽扯到的一個問題就是:如何給內(nèi)容排序?
當(dāng)用戶對內(nèi)容的喜好不一樣,可以按照興趣度來排序;但當(dāng)無法區(qū)分興趣度的時候(比如:用戶是新用戶;內(nèi)容都是新內(nèi)容;用戶對于某一標(biāo)簽下的內(nèi)容興趣度一樣),可以使用內(nèi)容質(zhì)量來做排序。click/pv是一種評判內(nèi)容質(zhì)量的方式。此外,使用卷積神經(jīng)網(wǎng)絡(luò)相關(guān)算法也可以構(gòu)建內(nèi)容質(zhì)量模型。
驚喜問題
推薦系統(tǒng)的驚喜目標(biāo)一直是一個難題,被稱作EE(Exploit & Explore)問題,bandit算法是解決這個問題的一個派系,就是估計置信區(qū)間的做法,然后按照置信區(qū)間的上界來進(jìn)行推薦,以UCB、LinUCB為代表的。簡單點說就是先不考慮你喜不喜歡就把質(zhì)量高的內(nèi)容推薦給你,后面根據(jù)用戶的行為反饋對推薦內(nèi)容作調(diào)整。具體的可以參見此篇文章:推薦系統(tǒng)的茍且和遠(yuǎn)方。
總結(jié)
借用推薦系統(tǒng)的那點事一文的幾句話做為結(jié)語:
- 實力派的【算法工程師】往往都是ABC[always be coding],這樣的算法工程師才能根據(jù)實際問題建立模型或者建立規(guī)則庫,是真正能解決問題的人。往往是一些有研究背景,經(jīng)驗豐富的研究員,更加重視工程,因為工程架構(gòu)上一些恰當(dāng)合理的設(shè)計,效果往往就能遠(yuǎn)遠(yuǎn)高過于模型算法優(yōu)化。
- 學(xué)院派的【算法工程師】往往是為了算法而算法,而不是為了解決推薦系統(tǒng)的問題去找最適合算法。這也是為什么大公司經(jīng)常招了一些博士畢業(yè)的算法工程師后,不是研究算法而是讓他們整天在那看數(shù)據(jù)報表?【因為發(fā)現(xiàn)算法沒啥好研究,只能讓他們在那看看報表找找規(guī)律了。】
- 【幾乎所有所謂的智能推薦算法都是花拳繡腿】
- 當(dāng)一個做推薦系統(tǒng)的部門開始重視【數(shù)據(jù)清理,數(shù)據(jù)標(biāo)柱,效果評測,數(shù)據(jù)統(tǒng)計,數(shù)據(jù)分析】這些所謂的臟活累活,這樣的推薦系統(tǒng)才會有救。
以上是推薦系統(tǒng)實踐的一些經(jīng)驗
原文出處:后端技術(shù)雜談 原文鏈接 轉(zhuǎn)載請與作者聯(lián)系,同時請務(wù)必標(biāo)明文章原始出處和原文鏈接及本聲明。 創(chuàng)作挑戰(zhàn)賽新人創(chuàng)作獎勵來咯,堅持創(chuàng)作打卡瓜分現(xiàn)金大獎
總結(jié)