mapreduce 算法_MapReduce算法–顺序反转
mapreduce 算法
這篇文章是介紹MapReduce算法的系列文章的另一部分,該書在使用MapReduce進行數據密集型文本處理中找到。 先前的文章是Local Aggregation , Local Aggregation PartII和創建共現矩陣 。 這次我們將討論階數反轉模式。 順序反轉模式利用的MapReduce來計算所需要的提前將被操縱的數據的減速推送數據的排序階段..你關閉此作為MapReduce的邊緣狀態之前,我強烈推薦您閱讀作為我們將討論如何利用排序的優勢,并使用自定義分區程序進行覆蓋,這兩個實用程序都是有用的工具。
盡管許多MapReduce程序是用較高級別的抽象(即Hive或Pig)編寫的,但了解較低級的情況仍然有幫助。順序反轉模式可在使用MapReduce進行數據密集型文本處理的第3章中找到。 。 為了說明順序倒置模式,我們將從同現矩陣模式中使用Pairs方法。 創建同現矩陣時,我們會跟蹤單詞一起出現的總次數。 在較高的層次上,我們采用“成對”方法并稍加改動,除了使映射器發出諸如(“ foo”,“ bar”)之類的單詞對外,我們還將發出(“ foo”,“ *”),并且將對每個單詞對執行此操作,因此我們可以輕松得出最左單詞出現頻率的總計數,并使用該計數來計算我們的相對頻率。 這種方法提出了兩個具體問題。 首先,我們需要找到一種方法來確保單詞對(“ foo”,“ *”)首先到達減速器。 其次,我們需要確保所有具有相同左單詞的單詞對都到達相同的縮減詞。 在解決這些問題之前,讓我們看一下我們的映射器代碼。
映射器代碼
首先,我們需要使用Pairs方法修改映射器。 在發出特定單詞的所有單詞對之后,在每個循環的底部,我們將發出特殊標記WordPair(“ word”,“ *”)以及在左側找到單詞的次數。
public class PairsRelativeOccurrenceMapper extends Mapper<LongWritable, Text, WordPair, IntWritable> {private WordPair wordPair = new WordPair();private IntWritable ONE = new IntWritable(1);private IntWritable totalCount = new IntWritable();@Overrideprotected void map(LongWritable key, Text value, Context context) throws IOException, InterruptedException {int neighbors = context.getConfiguration().getInt('neighbors', 2);String[] tokens = value.toString().split('\\s+');if (tokens.length > 1) {for (int i = 0; i < tokens.length; i++) {tokens[i] = tokens[i].replaceAll('\\W+','');if(tokens[i].equals('')){continue;}wordPair.setWord(tokens[i]);int start = (i - neighbors < 0) ? 0 : i - neighbors;int end = (i + neighbors >= tokens.length) ? tokens.length - 1 : i + neighbors;for (int j = start; j <= end; j++) {if (j == i) continue;wordPair.setNeighbor(tokens[j].replaceAll('\\W',''));context.write(wordPair, ONE);}wordPair.setNeighbor('*');totalCount.set(end - start);context.write(wordPair, totalCount);}}} }現在,我們已經生成了一種跟蹤遇到一個特定單詞的總次數的方法,我們需要確保那些特殊字符首先到達化簡器,以便可以計算出總數以計算相對頻率。 通過修改WordPair對象上的compareTo方法,我們將在MapReduce流程的排序階段為我們處理此問題。
修改后的排序
我們修改WordPair類上的compareTo方法,以便在右側遇到“ *”字符時,將特定對象推到頂部。
@Overridepublic int compareTo(WordPair other) {int returnVal = this.word.compareTo(other.getWord());if(returnVal != 0){return returnVal;}if(this.neighbor.toString().equals('*')){return -1;}else if(other.getNeighbor().toString().equals('*')){return 1;}return this.neighbor.compareTo(other.getNeighbor());}通過修改compareTo方法,我們現在可以確保將具有特殊字符的所有WordPair排在最前面,然后首先到達reducer。 這導致了我們的第二個專業化,我們如何保證具有給定左單詞的所有WordPair對象都將被發送到相同的reducer? 答案是創建一個自定義分區程序。
自定義分區
通過計算鍵的哈希碼對還原器的數量取模,將中間鍵改編為還原器。 但是我們的WordPair對象包含兩個單詞,因此采用整個對象的哈希碼顯然是行不通的。 我們需要修改一個自定義的分區程序,該分區程序在確定將哪個縮減程序發送到輸出時僅考慮左邊的單詞。
public class WordPairPartitioner extends Partitioner<WordPair,IntWritable> {@Overridepublic int getPartition(WordPair wordPair, IntWritable intWritable, int numPartitions) {return wordPair.getWord().hashCode() % numPartitions;} }現在,我們保證將所有具有相同左單詞的WordPair對象發送到相同的reducer。 剩下的就是構造一個化簡器以利用發送數據的格式。
減速器
為倒序反轉模式構建減速器很簡單。 這將涉及保持計數器變量和“當前”字變量。 減速器將檢查輸入鍵WordPair中右側的特殊字符“ *”。 如果左邊的單詞不等于“當前”單詞,我們將重新設置計數器并求和所有值,以獲得觀察到給定當前單詞的總次數。 現在,我們將處理下一個WordPair對象,對計數求和并除以我們的計數器變量,以獲得相對頻率。 該過程將繼續進行,直到遇到另一個特殊字符并重新開始。
public class PairsRelativeOccurrenceReducer extends Reducer<WordPair, IntWritable, WordPair, DoubleWritable> {private DoubleWritable totalCount = new DoubleWritable();private DoubleWritable relativeCount = new DoubleWritable();private Text currentWord = new Text('NOT_SET');private Text flag = new Text('*');@Overrideprotected void reduce(WordPair key, Iterable<IntWritable> values, Context context) throws IOException, InterruptedException {if (key.getNeighbor().equals(flag)) {if (key.getWord().equals(currentWord)) {totalCount.set(totalCount.get() + getTotalCount(values));} else {currentWord.set(key.getWord());totalCount.set(0);totalCount.set(getTotalCount(values));}} else {int count = getTotalCount(values);relativeCount.set((double) count / totalCount.get());context.write(key, relativeCount);}}private int getTotalCount(Iterable<IntWritable> values) {int count = 0;for (IntWritable value : values) {count += value.get();}return count;} }通過處理排序順序并創建自定義分區程序,我們已經能夠在計算所需的數據到達之前將數據發送到計算所需的化簡器。 盡管此處未顯示,但使用組合器來運行MapReduce作業。 這種方法也是“映射器內”合并模式的不錯選擇。
示例與結果
鑒于假期即將來臨,我覺得現在是時候針對查爾斯·狄更斯(Charles Dickens)的小說《圣誕節頌歌》(A Christmas Carol)進行訂單倒置模式的例子了。 我知道這很老套,但它能達到目的。
new-host-2:sbin bbejeck$ hdfs dfs -cat relative/part* | grep Humbug {word=[Humbug] neighbor=[Scrooge]} 0.2222222222222222 {word=[Humbug] neighbor=[creation]} 0.1111111111111111 {word=[Humbug] neighbor=[own]} 0.1111111111111111 {word=[Humbug] neighbor=[said]} 0.2222222222222222 {word=[Humbug] neighbor=[say]} 0.1111111111111111 {word=[Humbug] neighbor=[to]} 0.1111111111111111 {word=[Humbug] neighbor=[with]} 0.1111111111111111 {word=[Scrooge] neighbor=[Humbug]} 0.0020833333333333333 {word=[creation] neighbor=[Humbug]} 0.1 {word=[own] neighbor=[Humbug]} 0.006097560975609756 {word=[said] neighbor=[Humbug]} 0.0026246719160104987 {word=[say] neighbor=[Humbug]} 0.010526315789473684 {word=[to] neighbor=[Humbug]} 3.97456279809221E-4 {word=[with] neighbor=[Humbug]} 9.372071227741331E-4結論
雖然計算相對單詞出現頻率可能不是常見的任務,但我們已經能夠演示排序和使用自定義分區程序的有用示例,這是構建MapReduce程序時可以使用的好工具。 如前所述,即使您的大多數MapReduce是像Hive或Pig那樣以更高的抽象級別編寫的,了解幕后的情況仍然很有幫助。 謝謝你的時間。
參考: MapReduce算法-來自JCG合作伙伴 Bill Bejeck的《 隨機編碼思考》博客中的順序反轉 。
翻譯自: https://www.javacodegeeks.com/2012/12/mapreduce-algorithms-order-inversion.html
mapreduce 算法
總結
以上是生活随笔為你收集整理的mapreduce 算法_MapReduce算法–顺序反转的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: linux 命令 文件夹大小(linux
- 下一篇: 梦想成真…教学–专业的Java开发人员: