ItermCF的MR並行實現
ItermCF的MR並行實現
@(Hadoop)
ItermCF的基本思想
基於物品相似度的協同過濾推薦的思想大致可分為兩部分:
1.計算物與物之前的相似度
2.根據使用者的行為歷史,給出和歷史列表中的物品相似度最高的推薦
通俗的來講就是:
對於物品 A,根據所有使用者的歷史偏好,喜歡物品 A 的使用者都 喜歡物品 C,得出物品 A 和物品 C 比較相似,而使用者 C 喜歡物品 A,那麼可以推斷出 使用者 C 可能也喜歡物品 C。
ItermCF的演算法實現思路
對於以下的資料集:
UserId | ItermId | Preference |
---|---|---|
1 | 101 | 5 |
1 | 102 | 3 |
1 | 103 | 2.5 |
2 | 101 | 2 |
2 | 102 | 2.5 |
2 | 103 | 5 |
2 | 104 | 2 |
3 | 101 | 2 |
3 | 104 | 4 |
3 | 105 | 4.5 |
3 | 107 | 5 |
4 | 101 | 5 |
4 | 103 | 3 |
4 | 104 | 4.5 |
4 | 106 | 4 |
5 | 101 | 4 |
5 | 102 | 3 |
5 | 103 | 2 |
5 | 104 | 4 |
5 | 105 | 3.5 |
5 | 106 | 4 |
6 | 102 | 4 |
6 | 103 | 2 |
6 | 105 | 3.5 |
6 | 107 | 4 |
使用者評分矩陣
首先可以建立使用者對物品的評分矩陣,大概長這個樣子:
列為UserId,行為ItermId,矩陣中的值代表該使用者對該物品的評分。
從列的方向看,該矩陣的每一個列在mr程式中可以用一行簡單的字串來表示:
1 101:5,102:3,103:2.5 ...
這樣一來,上面的矩陣5個列就可以由5行類似的字串來構成。
那麼第一個mr任務的功能就是一個簡單的資料轉換過程:
1.輸入的key為行偏移量,value為每行內容,形如:1,101,5.0
2.在map階段,分割每行內容,輸出的key為1,value為101:5.0
3.在reduce階段,將UserId相同的所有評分記錄進行彙總拼接,輸出的key仍然為1,value形如:101:5,102:3,103:2.5 …
如此一來通過第一個mr任務得到了使用者的評分矩陣。
物品同現矩陣
該矩陣大概長這個樣子:
矩陣的值表示,兩個物品同時被使用者喜歡(評過分)的次數,例如:101和102這個組合被1,2,5三個使用者喜歡過,那麼在矩陣中101和102對應的值就是3。
這個矩陣的意義就是各個物品之間的相似度,為什麼可以這麼說?
如果兩個物品經常同時被很多使用者喜歡,那麼可以說這兩個物品是相似的,同時被越多的使用者喜歡(即為通同現度,上面矩陣中的值),這兩個物品的相似度就越高。
其實觀察可以發現,行和列上相同的(比如101和101)相比其他值(比如101和102,101和103)都是最大的,因為101和101就是同一個物品,相似度肯定是最大的。
從列的方向上看,這個同現矩陣的每一列在mr程式中可以通過下面簡單的字串來表示:
101:101 5
101:102 3
101:103 4
...
m*n的同現矩陣就由m個以上的字串(n行)組成。
那麼第二個mr任務的功能就是在第一個mr任務的輸出結果上得到物品同現矩陣:
1.輸入的key為偏移量,輸入的value為UserId+製表符+ItermId1:Perference1,ItermId2:Perference2…
2.輸入的value中,UserId和Perference是不需要關心的,觀察物品的同現矩陣,map階段的工作就是將每行包含的ItermId都解析出來,全排列組合作為key輸出,每個key的value記為1。
3.在reduce階段所做的就是根據key對value進行累加輸出。
如此一來便能夠得到物品的同現矩陣。
物品同現矩陣和使用者評分矩陣的相乘
物品同現矩陣*使用者評分矩陣=推薦結果:
為什麼兩個矩陣相乘可以得到推薦結果?
物品1和各個物品的同現度*使用者對各個物品的喜好度,反應出使用者對物品1的喜好度。
例如,要預測使用者3對103物品的喜好度,我們需要找到和103相似的物品,比如101物品,和103的同現度為4,是很類似的物品,使用者3對101的評分為2,那麼一定程度上可以反映出使用者對103的喜好度,101和103的相似度(即同現度)*使用者3對101的評分可以得到使用者3對103的喜好度權重,將使用者3對各個物品的權重相加,可以反映出使用者3對103的喜好度。
瞭解矩陣相乘的意義之後,第三個mr任務的功能就是實現兩個矩陣的相乘,並將結果輸出。
在這個mr任務中,這兩個矩陣的相乘可以這樣來計算:
將同現矩陣存入一個Map中,形如:
Map<String, Map<String, Double>> colItermOccurrenceMap = new HashMap<String, Map<String, Double>>();
同現矩陣中的每一行就是大Map中的一條記錄,每行對應的每列都在該記錄的小Map中。
在map階段的開始的時候初始化這個Map,輸入的value形如101:101 5,101:102 3,將101作為大Map的key,value為小Map,小Map的key為101/102,value為5/3。
由於map函式讀取檔案是併發讀取的,不能保證兩個輸入檔案的讀取順序(在同一個檔案中也不能保證),所以這裡使用Hadoop提供的分散式快取機制來對同現矩陣進行共享。
關於Hadoop的分散式快取機制請看:
Hadoop的DistributedCache機制
初始化同現矩陣之後,讀取評分矩陣的每一行,輸入的value為1 101:5,102:3,103:2.5 …
將每行的itermIds和對應的評分數提取出來,遍歷itermId,根據itermId到itermOccurrenceMap中找到對應的List集合,找到每個itermId在該集合中對應的itermId2記錄,將評分數*同現度,之後進行累加,以UserId:ItermID作為key,累加值作為value輸出。
reduce的工作就很簡單了,根據key對value進行累加輸出即可。
專案程式碼
作者:@小黑
相關文章
- 深入理解 Taier:MR on Yarn 的實現原理AIYarn
- 談談Hadoop MapReduce和Spark MR實現HadoopSpark
- python能實現並行嗎Python並行
- 一行 Python 程式碼實現並行Python並行
- [20190219]xargs -P實現並行執行.txt並行
- Java多執行緒並行處理任務的實現Java執行緒並行
- golang runtime實現多核並行任務Golang並行
- [原始碼解析] 模型並行分散式訓練 Megatron (3) ---模型並行實現原始碼模型並行分散式
- 探索:優雅地實現非同步方法的並行化非同步並行
- 怎樣用一行 Python 程式碼實現並行Python並行
- Java中實現並行請求兩種方式Java並行
- 在CPython中實現純Python函式的真正並行性Python函式並行
- pangrank演算法--PageRank演算法並行實現演算法並行
- 亞信安慧AntDB資料並行載入工具的實現(二)並行
- 任務排程並行演算法的Java簡單實現並行演算法Java
- 任務排程並行演算法的Python簡單實現並行演算法Python
- 並查集(一)並查集的幾種實現並查集
- 並查集java實現並查集Java
- 並查集-Java實現並查集Java
- 在no_ui中使用多程式實現多賬戶並行執行,並分配各自獨立的工作環境和策略UI並行
- 在 Golang 中使用 Go 關鍵字和 Channel 實現並行Golang並行
- [原始碼解析] PyTorch 流水線並行實現 (6)--平行計算原始碼PyTorch並行
- Sobol 序列並行化的實踐經驗並行
- 3.MR
- 本週精彩:Rust何時能實現零成本並行?Rust並行
- [原始碼解析] PyTorch 流水線並行實現 (4)--前向計算原始碼PyTorch並行
- [原始碼解析] PyTorch 流水線並行實現 (2)--如何劃分模型原始碼PyTorch並行模型
- 跑跑卡丁車手遊的“雙車道”:“輕重並行”實現經典新生並行
- MR多輸入
- 4.MR(1)
- 5.MR(2)
- 並查集的概念與演算法實現並查集演算法
- Java大型資料集合實現並行加速處理幾種方法 - DZoneJava並行
- oracle的並行世界Oracle並行
- 物聯網:實現sIoT配置並實現sIoT上mqtt訊息的通訊MQQT
- 說說instanceof和typeof的實現原理並自己模擬實現一個instanceof
- 使用 Parallel.ForEach 結合 Partitioner.Create 來實現每次並行處理5張圖片的邏輯。下面是一個示例程式碼,演示如何實現這種並行處理。Parallel並行
- 如何使用ISqlSugarClient進行資料訪問,並實現了統一的批次依賴注入SqlSugarclient依賴注入
- MR hadoop streaming job的學習 combinerHadoop