用Mapreduce實現推薦系統
提綱
- 什么是推薦系統
- 如何設計一個推薦系統
- mapreduce實現推薦系統
什么是推薦系統
- 當用戶沒有明確搜索目標時,預測用戶可能感興趣的物品并進行推薦的系統 ->電商網站;
- 當用戶有明確搜索目標時,協助用戶找到找到他們感興趣的信息 ->搜索引擎。
設計一個推薦系統
針對第一類推薦,以電影推薦為例,,數據集中包含用戶ID、電影ID、電影評分
1. 推薦系統中的算法;
- 基于用戶的協同過濾算法(User CF);
- 基于物品的系統過濾算法(Item CF)
- 。。。
基于用戶的協同過濾算法(User CF)
- 找到和目標用戶興趣相似的用戶集合;
-
找到這個集合中的用戶喜歡的,且目標用戶沒有聽說過的物品推薦給目標用戶。
基于物品的系統過濾算法(Item CF)
- 計算物品之間的相似度;
-
根據物品的相似度和用戶的歷史行為給用戶生成推薦列表。
2. 選擇其中適用一種算法;
這里采用的是Item CF。
- 電影網站中,用戶的數量遠遠大于物品的數量,找到相似用戶的工作遠遠大于找到相似物品的工作量;
- 用戶的興趣可能發生改變,這時需重復計算物品的相似度,而物品不會頻繁發生變化,降低了計算量;
- 根據用戶的歷史數據,更有說服力。
如何實現Item CF
如何定義不同電影之間的關系?
- 基于用戶的角度:歷史觀看記錄、歷史評分記錄、喜愛列表。
a. 如果某一個用戶同時觀看了2部類別差別很大的電影,這不能將這2部電影歸為相似,因為大部分的用戶肯定不會同時觀看2部差別很大的電影;
b. 如果用戶給電影打分,即便評分很低,也認為兩個電影相似,因為用戶是憑著自己的喜好去看的,評分低是由于本身的導演、演員、劇情等其他因素造成的。
- 基于電影的角度:電影類別、電影制造廠商。
如何體現不同電影間的相似性?
根據每個用戶的歷史觀看記錄,建立鄰接矩陣。
鄰接矩陣中,對角線表示觀看過該電影的用戶總數;非對角線表示同時觀看過兩部電影的用戶總數。
雖然找到了相似電影,但是此時不能直接就推薦給用戶,因為用戶可能只是對該電影感興趣,但是不一定看完以后會喜歡該電影。因此仍然額外需要考慮用戶的歷史評分。
如何區分不同電影間的差異性?
根據用戶的歷史評分記錄,區別對待每個用戶,為每個用戶建立評分矩陣;
這里B對M4、M5的評分不能默認為0,可以設置為B評分電影的平均分(3+7+8)/3。
- 矩陣計算得到推薦結果。
對最初的鄰接矩陣進行改進
- 歸一化處理的目的在于更加精確的表示兩部電影間的相似性。以M1、M3之間和M2、M3之間的關系為例。如果M1與M3之間的相似度為1,M2與M3之間的相似度為2。表面上,M2與M3的相似度更高,但是,假設M1與其他電影的相似度為0,M2除與M3以外還與其他電影有關系。顯然,我們不能認為絕對值大的相似度就一定高。
-
引入歸一化后,電影間的相似度比較建立在全局關系上,相似度的大小是一個相對值。除此之外,歸一化矩陣還體現了電影間的不對等關系,即M1對M2的關系與M2對M1的關系不是相等的概念,類似生活中的女神、屌絲間的關系,屌絲對應只有一個女神,女神對應著多個屌絲。
為甚么要做矩陣相乘(本質/意義):基于電影間的相關性和用戶評分的差異性得到一部電影可能帶給另一部電影的得分。以第一行M1對所有其他電影的關系為例,M2對M1的關系/權重是2/6,B對M2的評分是7,即M2有2/6的概率給M1帶來7分。
注意:
結果中B對M1的評分反而高于對M2的評分是因為評分矩陣中M4、M5初始設置的0,導致一個錯誤的結果。
3. 用Mapreduce實現。
input文件應該存儲什么數據結構?矩陣?
No!!!。1.浪費空間,存在許多空的單元;2.不利于修改,增加/減少一個用戶就需要修改整個矩陣。
這里采用user_id,movie_id,rating的結構存儲初始數據。
如何通過上述數據結構得到鄰接矩陣?
1.數據預處理,建立用戶歷史觀看過的矩陣->根據用戶id拆分數據,再根據相同用戶id合并數據
-
根據用戶id拆分數據 ->Mapper(key=userId,value=movieId+rating)
-
根據相同用戶id合并數據 ->Reducer
-
建立鄰接矩陣
疑問:
1.如何計算一部電影被多少人看過?
2.如何計算兩部電影同時被多少人看過?
Mapper
圖中只考慮了前2行的情況,省略了后面2行的情況
Reducer