當一個作推薦系統的部門開始重視【數據清理,數據標柱,效果評測,數據統計,數據分析】這些所謂的髒活累活,這樣的推薦系統纔會有救。算法
首先須要明確的就是推薦系統的目標,通常來講不外乎如下幾個:數據庫
用戶滿意性:首當其衝的,推薦系統主要就是爲了知足用戶的需求,所以準確率是評判一個推薦系統好壞的最關鍵指標。緩存
多樣性:雖然推薦系統最主要仍是知足用戶的興趣,可是也要兼顧內容的多樣性,對於權重不一樣的興趣都要作到兼顧。網絡
新穎性:用戶看到的內容是那些他們以前沒有據說過的物品。簡單的作法就是在推薦列表去掉用戶以前有過行爲的那些內容。機器學習
驚喜度:和新穎性相似,但新穎性只是用戶沒看到過的可是確實是和他行爲是相關的,而驚喜度是用戶既沒有看過和他以前的行爲也不相關,但用戶看到後的確是喜歡的。分佈式
實時性:推薦系統要根據用戶的上下文來實時更新推薦內容,用戶的興趣也是隨着時間而改變的,須要實時更新。 ide
推薦透明度:對於用戶看到的最終結果,要讓用戶知道推薦此內容的緣由。好比,「買過這本書的人同時也買過」、」你購買過的xx和此商品相似」。 性能
覆蓋率:挖掘長尾內容也是推薦系統很重要的目標。所以,推薦的內容覆蓋到的內容越多越好。學習
基於這些目標,推薦系統包括四種推薦方式:優化
熱門推薦:就是熱門排行榜的概念。這種推薦方式不只僅在IT系統,在日常的生活中也是到處存在的。這應該是效果最好的一種推薦方式,畢竟熱門推薦的物品都是位於曝光量比較高的位置的。
人工推薦:人工干預的推薦內容。相比於依賴熱門和算法來進行推薦。一些熱點時事如世界盃、nba總決賽等就須要人工加入推薦列表。另外一方面,熱點新聞帶來的推薦效果也是很高的。
相關推薦:相關推薦有點相似於關聯規則的個性化推薦,就是在你閱讀一個內容的時候,會提示你閱讀與此相關的內容。
個性化推薦:基於用戶的歷史行爲作出的內容推薦。
其中,前三者是和機器學習沒有任何關係的,但倒是推薦效果最好的三種方式。通常說來,這部份內容應該佔到總的推薦內容的80%左右,另外20%則是個性化推薦。
個性化推薦是機器學習應用的一個典型場景。在本質上和搜索引擎是同樣的,一樣是爲了解決信息過載的問題。搜索引擎某種意義上也是一個個性化推薦系統,可是其輸入特徵是能夠從搜索關鍵字直接能夠獲得的,而通常的推薦系統,輸入特徵則是須要機器學習才能獲得。
個性化推薦系統通常由日誌系統、推薦算法、內容展現UI三部分組成。
日誌系統:這是推薦系統的輸入源,是一個推薦系統全部信息的源頭。
推薦算法:這是推薦系統的核心,根據輸入數據得出最終的推薦結果的具體過程就在這裏。
內容展現UI:對於推薦結果如何展現,也是一個值得權衡的地方。以更好地知足推薦系統的目標,並能更好的收集用戶的行爲信息等。
其中,個性化推薦中最爲核心的推薦算法,目前比較流行的有如下幾種:
基於內容的推薦:根據內容自己的屬性(特徵向量)所做的推薦。
基於關聯規則的推薦:「啤酒與尿布」的方式,是一種動態的推薦,可以實時對用戶的行爲做出推薦。是基於物品之間的特徵關聯性所作的推薦,在某種狀況下會退化爲物品協同過濾推薦。
協同過濾推薦:與基於關聯規則的推薦相比是一種靜態方式的推薦,是根據用戶已有的歷史行爲做分析的基礎上作的推薦。可分爲物品協同過濾、用戶協同過濾、基於模型的協同過濾。其中,基於模型的協同又能夠分爲如下幾種類型:基於距離的協同過濾;基於矩陣分解的協同過濾,即Latent Factor Model(SVD);基於圖模型協同,即Graph,也叫社會網絡圖模型。
經過用戶歷史感興趣的信息,抽象信息內容共性(特徵向量),根據內容共性推薦其餘信息。
如何給一用戶推薦租房信息,簡要步驟以下
找到用戶A最近一個月內瀏覽過的租房信息集合
找到租房集合的具化內容(價格,平方,地理位置等)
抽象具化內容的共性內容 -- (2000每個月,50平方,下城區)
由這些共性內容做爲推薦條件查找其餘租房信息,並實施推薦
若是查詢的結果集太小,能夠縮小條件(下降抽象具化內容的共性內容的標準)召回,例如能夠將查詢條件縮小爲(2000每個月,50平方,無限制)或(2000每個月,無限制,無限制)。
經過找到興趣相投,或者有共同經驗的羣體,來向用戶推薦感興趣的信息。
如何經過協同過濾對用戶A進行電影推薦?簡要步驟以下
找到用戶A(user_id_1)的興趣愛好
找到與用戶A(user_id_1)具備相同電影興趣愛好的用戶羣體集合Set<user_id>
找到該羣體喜歡的電影集合Set<movie_id>
將這些電影Set<Movie_id>推薦給用戶A(user_id_1)
「協同過濾(Collaborative Filtering)」和「基於內容的推薦(Content-based Recommendation)」,都必須分析用戶的歷史行爲數據。若是系統沒有用戶的歷史行爲數據積累,如何實施推薦呢?對於新用戶A,沒有ta的歷史行爲數據,在ta點擊了item-X的場景下,能夠將與item-X最類似的item集合推薦給新用戶A。問題能夠轉化爲如何用一種通用的方法,表達item之間的類似性?
譬如租房有價格,地理位置,設施配套,大小,周邊交通等屬性,假設這裏是5個屬性,能夠把它看作一個五維空間中的點。
點擊了《戈雅公寓10幢304室》假設爲點N {價格:5000,地理位置:浦沿,大小:50m2,設置配套:空調洗衣機衣櫃,周邊交通:地鐵}
給每一個屬性設置權重,價格相同加5分,地理位置相近加3分,大小匹配加1分等。
求與點N距離最近的10個點,點《戈雅公寓10幢305室》的distance = f1(價格) + f2(地理位置) + … +f5(大小)=5 + 3 + … + 1=9
類似性推薦,原理大體如上,要說明的是:
因爲沒有用戶歷史行爲積累,不是個性化推薦,因此全部用戶的推薦結果都是相同的
通常來講,距離公式確實是線性的
通常來講,每一個維度的權重不同
這個線性公式,以及維度的權重,均可以經過機器學習訓練出來
關聯規則是數據挖掘中的概念,經過分析數據,找到數據之間的關聯。電商中常常用來分析購買物品之間的相關性,例如,「購買尿布的用戶,有大機率購買啤酒」,這就是一個關聯規則。關聯規則推薦的目標,是但願達到「將尿布放入購物車以後,再推薦啤酒」比「直接推薦啤酒」獲取有更好的售賣效果。
關聯規則A->B推薦,目標是,在「用戶將A放入購物車時,推薦B」比「單獨推薦B」獲取更好的效果
A->B的支持度,是用戶同時購買A和B機率
A->B的置信度,是用戶購買A的同時,有多大機率購買B
A->B的提高度,是「用戶購買A的同時,有多大機率購買B」與「直接購買B的機率」的比值
s(A)=3/5,s(B)=3/5,s(c)=1,s(D)=2/5,s(AB)=2/5,s(AC)=3/5。s(AB)等於同時購買A和B的數量除以總訂單量。
支持度評估商品包含在訂單中的「機率」,一個訂單,有多大機率包含這個商品。通常會先對支持度高的商品實施推薦,若是先實優化支持度低的商品,即便推薦效果翻倍,整體訂單提高效果也會頗有限。
分子:s(AB)是同時購買AB的比例
分母:s(A)是隻購買A的比例
兩者相除,獲得「購買了A,有多大機率購買B」,置信度的本質是條件機率。
c(C->B) = s(BC)/s(C)= (3/5)/(1) = 3/5 購買了C,有多大機率購買B
c(B->C) = s(BC)/s(B)= (3/5)/(3/5) = 1 購買了B,有多大機率購買C
c(B->C)=1,即:若是用戶購買商品B,100%會買C,那是否是意味着,若是用戶將商品B放入購物車,就能夠向用戶推薦商品C呢?
結合關聯規則的目標,雖然c(B->C)=1購買商品B,100%會買C,但s(C)=1直接推薦C,用戶也100%會買C。購買B與購買C是獨立事件,用戶買不買C和用戶買不買B沒有直接關係。這裏的關聯規則推薦,並無比直接推薦獲取更好的效果。用什麼指標來評估關聯規則推薦的效果呢?提高度!
分子:c(A->B),購買A時,有多大機率同時購買B
分母:s(B),有多大機率直接購買B
A->B關聯規則推薦c(A->B),與s(B)直接推薦B,的比值,能夠用來評估推薦效果:
大於1,說明有效,在購買A時推薦B,比直接推薦B,效果更好
等於1,說明無關,購買A與購買B,是獨立事件
小於1,說明負相關,購買A時推薦B,效果還不如直接推薦B
可知,一個推薦系統主要有如下模塊組成:
用戶行爲日誌:此部分主要是用戶行爲日誌的存儲,屬於數據統計的一部分, 存儲在hive中。
數據ETL-1:將用戶日誌轉換爲推薦算法所須要的數據格式。對原始的用戶行爲等數據進行清洗、加工,如字段、屬性、格式化等,做爲下一步推薦算法的輸入。
推薦算法:是個性化推薦最主要的部分,包括經過用戶行爲計算相關內容以及推薦結果等。
數據ETL-2: 將推薦算法獲得的結果進一步加工爲存儲模塊的輸入數據。對推薦算法產生的結果進行清洗、格式化等,做爲下一步存儲模塊的輸入。
用戶畫像存儲:存儲用戶的偏好以及行爲數據,如對內容關鍵字的偏好、點擊過哪些內容等。
推薦結果存儲:存儲各類推薦算法產生的推薦結果,能夠分爲兩部分:{用戶 : itemList}推薦結果,爲用戶推薦的內容列表;{item : itemList}推薦結果,與item相關的內容列表。
服務調用模塊:整合推薦結構,對外提供提供推薦的調用接口。
在線業務系統的日誌接入數據高速公路,再由數據高速公路迅速運轉到離線數據處理平臺和在線流計算平臺;離線數據處理平臺週期性地以批處理方式加工過去一段時間的數據,獲得人羣標籤和其餘模型參數,存放在高速緩存中,供在線業務系統使用,與此同時,在線流計算平臺實時對線上的日誌數據作處理,對離線計算出的數據進行補充、修正等;在線業務系統綜合離線特徵和在線特徵使用必定的邏輯獲得輸出供業務使用,產生的日誌流入數據高速公路。
對於個性化推薦系統來講,推薦算法應該是其最核心的部分。目前有不少流行的算法,好比:
基於內容和用戶畫像的推薦:此種算法,http://www.rowkey.me/blog/2016/04/07/up-recommend/。
基於矩陣分解的推薦: 基於SVD/ALS算法對用戶進行內容推薦。相比起SVD,ALS更加適合解決稀疏矩陣的問題。Spark mlib中已經集成了對als算法的實現,須要作的就是在etl-1中把數據轉換爲als須要的數據格式以及調整als算法的各類參數。有一篇文章比較具體地描述瞭如何使用spark來作基於ALS的推薦:http://colobu.com/2015/11/30/movie-recommendation-for-douban-users-by-spark-mllib/。
用戶&物品協同過濾推薦:包括UserBased CF和ItemBased CF。對於這二者,須要根據業務的不一樣來選擇不一樣的算法。當用戶很是多的時候,考慮到維護用戶矩陣的成本,通常是不推薦選擇用戶協同過濾的,而對於候選item不少的時候,則不推薦使用物品協同過濾。
推薦算法的輸出結果通常是一個用戶對應一個item列表或者是一個item對應一個item列表。此部分主要考慮的是算法的時間複雜度,無論是哪種算法,一旦用戶或者內容數據上了百萬級別,都須要經過分佈式計算如MapReduce、Spark等來進行解決。
推薦算法的基本流程以下圖所示:
存儲用戶的偏好以及行爲數據等信息。對於偏好,採用標籤量化來表示,是一種隨着時間衰減的值。對於用戶畫像,是批量寫入、實時讀取,因此存儲要着重考慮讀的性能。能夠選擇使用Redis集羣做爲技術方案,可以最大知足讀的性能,缺點是Redis的成本昂貴且不支持auto index。也可以使用Hbase做爲存儲,使用ElasricSearch構建二級索引,以應對根據多種維度彙集用戶的需求(好比過濾某一個標籤下的全部用戶)。
對各類推薦算法計算出的推薦結果的存儲。存儲空間要求大,格式複雜。對於存儲的容量和讀寫性能要求都比較高。能夠選擇使用Redis集羣做爲此部分的存儲方案。
整合用戶畫像和推薦結果兩部分數據,向外提供推薦調用的接口。主要是數據庫IO調用開銷。
根據用戶id,獲取推薦的item列表。
根據item,獲取相關聯的item列表。
根據用戶id, 獲取用戶畫像。
該模塊須要採起必定的策略聚合多種推薦算法的推薦結果,直接面向業務。策略因爲會隨着面向的業務不一樣而不一樣,須要可配置化。同時也提供對外暴露用戶畫像的接口,使得業務方可使用用戶畫像作針對性的處理。能夠採用RPC機制對外暴露服務接口。
實時性問題
因爲計算用戶、item矩陣或者進行矩陣分解是須要離線進行且比較耗時,所以協同的推薦算法是很難達到實時性的。實時部分的推薦主要依靠基於用戶畫像的推薦來進行。最終的推薦列表是根據必定的策略對這兩部分進行聚合的結果。
時效性內容指的是那些與時間強相關的內容,好比新聞、時事等。若是一條10天前xx球員得到冠軍的新聞如今被推薦了出來,可想用戶確定是莫名其妙或者是很失望的。所以,對於時效性內容,須要與普通的待推薦的內容區分開,作單獨的推薦或者不走個性化推薦。
無論使用何種推薦算法,都會面臨冷啓動問題:當用戶是新用戶,如何給用戶推薦item呢?當內容是新內容,如何推薦給用戶?
對於新用戶,能夠採起的一種策略就是採用熱門推薦或者人工推薦,把絕大多人關心的內容推薦出來。
對於內容,能夠將內容分爲新內容池和待推薦內容池。新內容產生時,首先進入新內容池。每次推薦的時候,先重新內容池作候選推薦,並給此內容的傳播度+1,直到其傳播度大於一個閾值的時候,將其移至待推薦內容池。這樣既能夠解決新內容的冷啓動問題也在必定程度上能夠保證新內容的曝光量。
在基於用戶畫像的推薦算法中,取出用戶的多個標籤,而後根據相關度從不一樣的標籤中取不一樣數量的內容,這樣既兼顧了用戶的多種興趣也可以在必定程度上解決多樣性的問題。
如:用戶具備tag:A B C D,相關度爲wA wB wC wD,Total推薦爲總共須要推薦的條數,那麼
RecommendList(u) = A[Total推薦 * wA] + B[Total推薦 * wB] + C[Total推薦 * wC] + D[Total推薦 * wD]
無論是熱門推薦、人工推薦仍是取某一標籤下的內容列表都牽扯到的一個問題就是:如何給內容排序?
當用戶對內容的喜愛不同,能夠按照興趣度來排序;但當沒法區分興趣度的時候(好比:用戶是新用戶;內容都是新內容;用戶對於某一標籤下的內容興趣度同樣),可使用內容質量來作排序。click/pv是一種評判內容質量的方式。此外,使用卷積神經網絡相關算法也能夠構建內容質量模型。
推薦系統的驚喜目標一直是一個難題,被稱做EE(Exploit & Explore)問題,bandit算法是解決這個問題的一個派系,就是估計置信區間的作法,而後按照置信區間的上界來進行推薦,以UCB、LinUCB爲表明的。簡單點說就是先不考慮你喜不喜歡就把質量高的內容推薦給你,後面根據用戶的行爲反饋對推薦內容做調整。