您好,登錄后才能下訂單哦!
這期內容當中小編將會給大家帶來有關mapreduce中怎么實現矩陣相乘,文章內容豐富且以專業的角度為大家分析和敘述,閱讀完這篇文章希望大家可以有所收獲。
設,,那么
矩陣乘法要求左矩陣的列數與右矩陣的行數相等,的矩陣,與的矩陣相乘,結果為的矩陣。
現在我們來分析一下,哪些操作是相互獨立的(從而可以進行分布式計算)。很顯然,的計算和的計算是互不干擾的;事實上,中各個元素的計算都是相互獨立的。這樣,我們在Map階段,可以把計算所需要的元素都集中到同一個key中,然后,在Reduce階段就可以從中解析出各個元素來計算;的其他元素的計算同理。
我們還需要注意,會被、……的計算所使用,會被、……的計算所使用。也就是說,在Map階段,當我們從HDFS取出一行記錄時,如果該記錄是的元素,則需要存儲成個<key, value>對,并且這個key互不相同;如果該記錄是的元素,則需要存儲成個<key, value>對,同樣的,個key也應互不相同;但同時,用于計算的、存放、……和、……的<key, value>對的key應該都是相同的,這樣才能被傳遞到同一個Reduce中。
經過以上分析,整個計算過程設計為:
(1)在Map階段,把來自表的元素,標識成條<key, value>的形式。其中,;把來自表的元素,標識成條<key, value>形式,其中,。
于是乎,在Map階段,我們實現了這樣的戰術目的:通過key,我們把參與計算的數據歸為一類。通過value,我們能區分元素是來自還是,以及具體的位置。
(2)在Shuffle階段,相同key的value會被加入到同一個列表中,形成<key, list(value)>對,傳遞給Reduce,這個由Hadoop自動完成。
(3)在Reduce階段,有兩個問題需要自己問問:
當前的<key, list(value)>對是為了計算的哪個元素?
list中的每個value是來自表或表的哪個位置?
第一個問題可以從key中獲知,因為我們在Map階段已經將key構造為形式。第二個問題,也可以在value中直接讀出,因為我們也在Map階段做了標志。
接下來我們所要做的,就是把list(value)解析出來,來自的元素,單獨放在一個數組中,來自的元素,放在另一個數組中,然后,我們計算兩個數組(各自看成一個向量)的點積,即可算出的值。
示例矩陣和相乘的計算過程如下圖所示:
其中map階段:
public static class MatrixMap extends Mapper<Object, Text, Text, Text>{ private int sum3 = 0; //存放矩陣a的行數 private int sum4 = 0; //存放矩陣b的行數 @Override protected void map(Object key, Text value, Context context) throws IOException, InterruptedException { String[] lines = value.toString().split(","); String url = ((FileSplit)context.getInputSplit()).getPath().toString(); //取出文件路徑名,判斷數據來源分別增加其行數 if(url.contains("matrix3")) sum3++; if(url.contains("matrix4")) sum4++; for(int m = 0; m < lines.length; m++){ // 遍歷矩陣列數,分別與行數組成key為(i,k),value為(a,j,v)的數據輸出 if(url.contains("matrix3") && lines.length == matrix_j){ for (int i = 1; i <= matrix_k; i++){ context.write(new Text(sum3+","+i), new Text("a,"+(m+1)+","+lines[m])); } }else if(url.contains("matrix4") && lines.length == matrix_k){ for (int i = 1; i <= matrix_i; i++){ context.write(new Text(i+","+(m+1)), new Text("b,"+sum4+","+lines[m])); } } } } }
reduce階段:
public static class MatrixReduce extends Reducer<Text, Text, Text, Text>{ private Map<Integer, Integer> matrix_a; private Map<Integer, Integer> matrix_b; @Override protected void reduce(Text key, Iterable<Text> values, Context context) throws IOException, InterruptedException { matrix_a = new HashMap<Integer, Integer>(); matrix_b = new HashMap<Integer, Integer>(); for(Text value : values){ //循環分辨values中值是矩陣a或是b的,并存入map集合a和b中 String line = value.toString(); if(line.startsWith("a,")){ String[] lines = line.split(","); if(lines.length == 3) matrix_a.put(Integer.parseInt(lines[1]), Integer.parseInt(lines[2])); }else{ String[] lines = line.split(","); if(lines.length == 3) matrix_b.put(Integer.parseInt(lines[1]), Integer.parseInt(lines[2])); } } int a_value = 0; int b_value = 0; int result = 0; //分別取出a和b集合中,計算結果放入result中 for(int i = 1; i <= matrix_j; i++){ if(matrix_a.get(i) != null && matrix_b.get(i) != null){ a_value = matrix_a.get(i); b_value = matrix_b.get(i); result += a_value * b_value; } } context.write(key, new Text(result+"")); } }
主程序:
public static void run(String time, Configuration conf) throws IOException, ClassNotFoundException, InterruptedException{ // 需求輸出文件路徑 String outpath = VALUE_FSNAME+ "/data/test_out/zk/matrix-"+time; // 需求輸入文件路徑 String input1 = VALUE_FSNAME+"/data/test_in/matrix3"; String input2 = VALUE_FSNAME+"/data/test_in/matrix4"; File jarFile = EJob.createTempJar("bin"); @SuppressWarnings("deprecation") Job job = new Job(conf, "Test-Matrix"); job.setJarByClass(TestMatrix1.class); job.setMapperClass(MatrixMap.class); job.setReducerClass(MatrixReduce.class); job.setOutputKeyClass(Text.class); job.setOutputValueClass(Text.class); job.setNumReduceTasks(1); job.setInputFormatClass(TextInputFormat.class); job.setOutputFormatClass(TextOutputFormat.class); FileInputFormat.addInputPaths(job, input1+","+input2);; FileOutputFormat.setOutputPath(job, new Path(outpath)); // 提交job if (job.waitForCompletion(true)) { System.err.println("計算完成!"); } else { System.err.println("error!請檢查程序!"); } }
最后,大家請看一下原始數據:
matrix1:
1,2,3 4,5,0 7,8,9 10,11,12
matrix2:
10,15 0,2 11,9
上述就是小編為大家分享的mapreduce中怎么實現矩陣相乘了,如果剛好有類似的疑惑,不妨參照上述分析進行理解。如果想知道更多相關知識,歡迎關注億速云行業資訊頻道。
免責聲明:本站發布的內容(圖片、視頻和文字)以原創、轉載和分享為主,文章觀點不代表本網站立場,如果涉及侵權請聯系站長郵箱:is@yisu.com進行舉報,并提供相關證據,一經查實,將立刻刪除涉嫌侵權內容。