轉載自:算法
https://mp.weixin.qq.com/s/d6bCGT8B4h5pfI77TvLicA緩存
這篇文章屬於推薦系統的入門篇,本文暫不考慮線上環境的海量數據,目的是先瞭解清楚推薦系統的基本構成,我會經過圖解推薦算法以及程序demo的形式展開,內容包括:微信
01 走進推薦系統的世界
架構
1. 推薦系統到底解決的是什麼問題?併發
推薦系統從20世紀90年代就被提出來了,可是真正進入大衆視野以及在各大互聯網公司中流行起來,仍是最近幾年的事情。app
隨着移動互聯網的發展,愈來愈多的信息開始在互聯網上傳播,產生了嚴重的信息過載。所以,如何從衆多信息中找到用戶感興趣的信息,這個即是推薦系統的價值。精準推薦解決了用戶痛點,提高了用戶體驗,最終便能留住用戶。機器學習
推薦系統本質上就是一個信息過濾系統,一般分爲:召回、排序、重排序這3個環節,每一個環節逐層過濾,最終從海量的物料庫中篩選出幾十個用戶可能感興趣的物品推薦給用戶。
ide
推薦系統的分階段過濾流程高併發
2. 推薦系統的應用場景哪裏有海量信息,哪裏就有推薦系統,咱們天天最經常使用的APP都涉及到推薦功能:性能
頭條、京東、網易雲音樂中的推薦功能
推薦系統的應用場景一般分爲如下兩類:
基於物品維度的推薦:根據用戶當前瀏覽的標的物進行推薦,好比打開京東APP的商品詳情頁,會推薦和主商品相關的商品給你。
搜索和推薦是AI算法最多見的兩個應用場景,在技術上有相通的地方。這裏提到廣告,主要考慮不少沒作過廣告業務的同窗不清楚爲何廣告和搜索、推薦會有關係,因此作下解釋。
推薦:不具備目的性,依賴用戶的歷史行爲和畫像數據進行個性化推薦。
廣告:藉助搜索和推薦技術實現廣告的精準投放,能夠將廣告理解成搜索推薦的一種應用場景,技術方案更復雜,涉及到智能預算控制、廣告競價等。
02 推薦系統的總體架構
推薦系統的總體架構
計算平臺:負責對底層的各類異構數據進行清洗、加工,離線計算和實時計算。
數據存儲層:存儲計算平臺處理後的數據,根據須要可落地到不一樣的存儲系統中,好比Redis中能夠存儲用戶特徵和用戶畫像數據,ES中能夠用來索引物品數據,Faiss中能夠存儲用戶或者物品的embedding向量等。
召回層:包括各類推薦策略或者算法,好比經典的協同過濾,基於內容的召回,基於向量的召回,用於託底的熱門推薦等。爲了應對線上高併發的流量,召回結果一般會預計算好,創建好倒排索引後存入緩存中。
融合過濾層:觸發多路召回,因爲召回層的每一個召回源都會返回一個候選集,所以這一層須要進行融合和過濾。
排序層:利用機器學習或者深度學習模型,以及更豐富的特徵進行重排序,篩選出更小、更精準的推薦集合返回給上層業務。
推薦引擎的核心功能和技術方案
特徵計算因爲數據量大,一般採用大數據的離線和實時處理技術,像Spark、Flink等,而後將計算結果保存在Redis或者其餘存儲系統中(好比HBase、MongoDB或者ES),供召回和排序模塊使用。 召回算法的做用是:從海量數據中快速獲取一批候選數據,要求是快和儘量的準。這一層一般有豐富的策略和算法,用來確保多樣性,爲了更好的推薦效果,某些算法也會作成近實時的。 排序算法的做用是:對多路召回的候選集進行精細化排序。它會利用物品、用戶以及它們之間的交叉特徵,而後經過複雜的機器學習或者深度學習模型進行打分排序,這一層的特色是計算複雜可是結果更精準。03 圖解經典的協同過濾算法
瞭解了推薦系統的總體架構和技術方案後,下面帶你們深刻一下算法細節。這裏選擇圖解的是推薦系統中的明星算法:協同過濾(Collaborative Filtering,CF)。 對於工程同窗來講,可能以爲 AI 算法晦澀難懂,門檻過高,確實不少深度學習算法的確是這樣,可是協同過濾倒是一個簡單同時效果很好的算法,只要你有初中數學的基礎就能看懂。1. 協同過濾是什麼?
協同過濾算法的核心就是「找類似」,它基於用戶的歷史行爲(瀏覽、收藏、評論等),去發現用戶對物品的喜愛,並對喜愛進行度量和打分,最終篩選出推薦集合。它又包括兩個分支:
基於用戶的協同過濾示例
基於物品的協同過濾:Item-CF,核心是找類似的物品。好比下圖中,物品 a 和物品 b 同時被用戶 A,B,C 購買了,那麼物品 a 和 物品 b 被認爲是類似的,由於它們的共現次數很高。這樣,若是用戶 D 購買了物品 a,則能夠將和物品 a 最類似的物品 b 推薦給用戶 D。
前面講到,協同過濾的核心就是找類似,User-CF是找用戶之間的類似,Item-CF是找物品之間的類似,那到底如何衡量兩個用戶或者物品之間的類似性呢?
咱們都知道,對於座標中的兩個點,若是它們之間的夾角越小,這兩個點越類似,這就是初中學過的餘弦距離,它的計算公式以下:
舉個例子,A座標是(0,3,1),B座標是(4,3,0),那麼這兩個點的餘弦距離是0.569,餘弦距離越接近1,表示它們越類似。
清楚了類似性的定義後,下面以Item-CF爲例,詳細說下這個算法究竟是如何選出推薦物品的?
第一步:整理物品的共現矩陣
假設有 A、B、C、D、E 5個用戶,其中用戶 A 喜歡物品 a、b、c,用戶 B 喜歡物品 a、b等等。第二步:計算物品的類似度矩陣
對於 Item-CF 算法來講,通常不採用前面提到的餘弦距離來衡量物品的類似度,而是採用下面的公式 :基於第1步計算出來的共現矩陣以及每一個物品的喜歡人數,即可以構造出物品的類似度矩陣:
上面的公式有點抽象,直接看例子更容易理解,假設我要給用戶 E 推薦物品,前面咱們已經知道用戶 E 喜歡物品 b 和物品 c,喜歡程度假設分別爲 0.6 和 0.4。那麼,利用上面的公式計算出來的推薦結果以下:
04 從0到1搭建一個推薦系統
有了上面的理論基礎後,咱們就能夠用 Python 快速實現出一個推薦系統。1. 選擇數據集
這裏採用的是推薦領域很是經典的 MovieLens 數據集,它是一個關於電影評分的數據集,官網上提供了多個不一樣大小的版本,下面以 ml-1m 數據集(大約100萬條用戶評分記錄)爲例。
下載解壓後,文件夾中包含:ratings.dat、movies.dat、users.dat 3個文件,共6040個用戶,3900部電影,1000209條評分記錄。各個文件的格式都是同樣的,每行表示一條記錄,字段之間採用 :: 進行分割。
以ratings.dat爲例,每一行包括4個屬性: UserID, MovieID, Rating, Timestamp。 經過腳本能夠統計出不一樣評分的人數分佈:程序主要使用數據集中的 ratings.dat 這個文件,經過解析該文件,抽取出 user_id、movie_id、rating 3個字段,最終構造出算法依賴的數據,並保存在變量 dataset 中,它的格式爲:dict[user_id][movie_id] = rate
基於第 2 步的 dataset,能夠進一步統計出每部電影的評分次數以及電影的共生矩陣,而後再生成類似度矩陣。
最後,能夠基於類似度矩陣進行推薦了,輸入一個用戶id,先針對該用戶評分過的電影,依次選出 top 10 最類似的電影,而後加權求和後計算出每一個候選電影的最終評分,最後再選擇得分前 5 的電影進行推薦。
下面選擇 UserId=1 這個用戶,看下程序的執行結果。因爲推薦程序輸出的是 movieId 列表,爲了更直觀的瞭解推薦結果,這裏轉換成電影的標題進行輸出。
最終推薦的前5個電影爲:
05 線上推薦系統的挑戰
經過上面的介紹,你們對推薦系統的基本構成應該有了一個初步認識,可是真正運用到線上真實環境時,還會遇到不少算法和工程上的挑戰,絕對不是幾十行 Python 代碼能夠搞定的。
一、上面的示例使用了標準化的數據集,而線上環境的數據是非標準化的,所以涉及到海量數據的收集、清洗和加工,最終構造出模型可以使用的數據集。
二、複雜且繁瑣的特徵工程,都說算法模型的上限由數據和特徵決定。對於線上環境,須要從業務角度選擇出可用的特徵,而後對數據進行清洗、標準化、歸一化、離散化,並經過實驗效果進一步驗證特徵的有效性。
三、算法複雜度如何下降?好比上面介紹的Item-CF算法,時間和空間複雜度都是O(N×N),而線上環境的數據都是千萬甚至上億級別的,若是不作算法優化,可能幾天都跑不出數據,或者內存中根本放不下如此大的矩陣數據。
四、實時性如何知足?由於用戶的興趣隨着他們最新的行爲在實時變化的,若是模型只是基於歷史數據進行推薦,可能結果不夠精準。所以,如何知足實時性要求,以及對於新加入的物品或者用戶該如何推薦,都是要解決的問題。
五、算法效果和性能的權衡。從算法角度追求多樣性和準確性,從工程角度追求性能,這二者之間必須找到一個平衡點。
六、推薦系統的穩定性和效果追蹤。須要有一套完善的數據監控和應用監控體系,同時有 ABTest 平臺進行灰度實驗,進行效果對比。