近期參加了DataWhale組織的組隊學習,加入了其中的新聞推薦系統的學習,專門開了一個分類來記錄學習的過程!
項目地址:Fun-rec。
先給出整個新聞推薦系統的框架:
可以很清楚地看到,整個系統被划分成兩個部分:offline,online。
offline
offline部分主要包含:
- 新聞物料的爬取
- 物料畫像處理
- 用戶畫像更新
- 生成推薦頁列表
- 生成熱門頁列表
新聞物料的爬取
每天23點爬取新浪新聞當天的新聞數據,因為晚上的物料更多一些。爬取的新聞物料存入MongoDB數據庫中。爬取的過程:
- 每天定時從新浪新聞上面爬取當天的新聞,並將新聞存入到mongodb數據庫中
- 爬取新聞是一個增量的過程,每天只爬取當天的新聞
- 新聞爬取的時候需要提前之前物料池中的所有物料的標題給存下來用來去重
物料畫像處理
這一部分將爬取到的新聞物料放入物料池,並對物料池(包括之前已經在物料池的新聞)中的物料進行畫像(包括新聞的靜態特征,以及動態特征,如點贊數等)處理。主要過程:
- 將爬取的新聞原始數據處理成畫像數據
- 將處理好的特征畫像中需要展示的數據放到redis中
用戶畫像更新
更新注冊了的用戶的畫像(存放在MongoDB中),畫像特征有:
- 基本屬性特征,如用戶名、性別、城市等
- 動態特征:歷史喜歡最多的Top3的新聞類別、歷史喜歡新聞的Top3的關鍵詞、用戶喜歡新聞的平均熱度、用戶15天內喜歡的新聞數量
關於物料的離線部分到此為止,接下來就是離線生成展示內容了,先看一下本項目中的新聞推薦系統的界面:
從上面可以看出,每個用戶登陸后會有兩個列表:一個是推薦列表、一個是熱門列表。
- 推薦列表是“千人千面”的,每個用戶的推薦列表都是不一樣的,注意在離線部分,會為每個用戶生成推薦列表(新用戶則根據冷啟動方法生成,老用戶則按照推薦算法生成)
- 在離線部分,熱門列表是事先生成好的。離線部分會對物料池中新聞(並不是所有新聞,二十經過過濾后的新聞,比如最近10天內的新聞)計算熱度值,再排序得到一個熱門新聞列表,這個列表作為每個用戶熱門列表的模板(這里說它是“模板”是因為每個用戶的熱門列表是不一樣的,“模板”作為用戶的初始熱門列表,當給用戶曝光時,還需要去除用戶已經看過的新聞)
所謂熱門頁, 就是對於每篇文章,會根據它的發布時間,用戶對它的行為記錄(獲得的點贊數,收藏數和閱讀數)去計算該文章的熱度信息, 然后根據熱度值進行排序得到, 所以計算文章的熱門記錄, 只需要文章畫像的動靜態信息即可,天級更新。
至此,offline部分結束了!!!
online
線上是為用戶在使用系統的過程中觸發的行為提供一系列服務,使用流程:
- 當用戶剛進入系統的時候,會進入新聞的推薦頁面,此時系統會為該用戶獲取推薦頁文章並進行展示
- 當用戶進入熱門頁, 系統就會為該用戶獲取熱門頁列表並進行展示
以下這段內容引用自這里。
-
獲取推薦頁列表:這個服務在用戶剛進入系統,以及在推薦頁中瀏覽文章刷新下拉過程中進行觸發,當系統觸發該服務的時候,首先會判斷該用戶是新用戶還是老用戶
- 如果是新用戶,就從離線存儲好的冷啟動列表(離線部分生成)中讀取推薦列表,選擇指定的數目(比如一次觸發給用戶推薦10篇)的文章推薦,但推薦之前,需要去除已曝光的文章(避免重復曝光,影響用戶體驗),所以對於每個用戶,我們還會記錄一份已曝光列表,方便我們去重,同時,當批文章曝光出去,還要即使更新我們的曝光列表。
- 如果是老用戶,就從離線存儲好的個性化推薦列表中讀取, 和上面一樣, 選擇指定數目的文章,去掉曝光,生成最終推薦列表,同時更新用戶曝光記錄。
-
獲取熱門頁列表: 這個服務是用戶點擊熱門頁,以及在熱門頁中瀏覽文章刷新下來過程中進行觸發,當該服務觸發的時候,依然會判斷新用戶和老用戶
- 如果是新用戶,需要從離線存儲好的公共冷啟動模板中為該用戶生成一份熱門頁列表,然后獲取,選擇指定數目文章推薦,和上面一樣,去曝光,生成最終推薦列表,更新曝光記錄。
- 如果是老用戶,從離線存儲好的該用戶熱門列表中讀取,選擇指定數目文章推薦,去曝光,生成最終推薦列表,更新曝光記錄。
服務端代碼
源碼地址:news_rec_server。
整理后的服務器端代碼結構:
具體的代碼分析就留在后續的任務中慢慢做吧。