Recude処理
続いてReduce処理です。
Reduce処理の入力はMap処理の出力になります。名詞のみに絞った場合下記のようになりました。
1287144000 迫力
1287144000 香川
1287144000 w
1287144600 利根川
1287144600 利根川
1287144600 キター
1287144600 !
次に出力です。
1287144000 1,迫力
1287144000 1,香川
1287144000 1,w
1287144600 2,利根川
1287144600 1,キター
1287144600 1,!
丸めたunixtimeごとに出現回数の多い単語順にベスト5が出力されます。これが最終的なMapReduceの出力となります
それでは実際のコードを見てみましょう。J2chReduerクラスです。
static class J2chReducer extends Reducer <IntWritable, Text, IntWritable, Text>
{
public void reduce(IntWritable key, Iterable<Text> values, Context context)
throws IOException, InterruptedException
{
// hashtableオブジェクトを作成
// Text=カウントというハッシュを作りたい。
Hashtable kvs = new Hashtable();
// valueにTextのリストが渡されるのでイテレーションする
for( Text value : values )
{
// Textの取り出し。
String k = value.toString();
// kvsオブジェクトに存在すれば。
if ( kvs.containsKey( k ))
{
// すでに存在するキーのバリューを+1する。出現回数を+1する。
Integer n = kvs.get(k) + 1;
kvs.put(k, n);
}
else // 無ければ
{
// kvsオブジェクトにキーと出現回数(1)を追加する。
kvs.put(k, 1);
}
}
// 配列のリストを作成してkvsの中身をセットする。
ArrayList entries = new ArrayList(kvs.entrySet());
// バリューの中身でソートする。(出現回数でソートする)
Collections.sort(entries, new Comparator(){
public int compare(Object obj1, Object obj2){
Map.Entry ent1 =(Map.Entry)obj1;
Map.Entry ent2 =(Map.Entry)obj2;
int val1 = Integer.parseInt(ent1.getValue().toString());
int val2 = Integer.parseInt(ent2.getValue().toString());
return (val2 - val1); // 降順
}
});
// ソート後の配列のリストを走査(降順)
// 最大4まで配列を回す
for( int i = 0; i < entries.size() && i < 5; i++ )
{
String word = (String)((Map.Entry)entries.get(i)).getKey();
int cnt = Integer.parseInt(((Map.Entry)entries.get(i)).getValue().toString());
// キーはIntWritable,バリューはText
context.write(key, new Text( key + "," + cnt + "," + word));
}
}
}
こちらもJ2chMapperと同様に,
static class J2chReducer extends Reducer <IntWritable, Text, IntWritable, Text>
の部分が,
- 入力キー,
バリュー (IntWritable, Text) - 出力キー,
バリュー (IntWritable, Text)
を定義しています。Mapperの出力とReducerの入力が同じであることに注意してください。
さて,
1287144000 迫力
1287144000 香川
1287144000 w
1287144600 利根川
1287144600 利根川
1287144600 キター
1287144600 !
実際には
1287144000 [迫力,香川,w]
1287144600 [利根川,利根川,キター,!]
というふうに,
リストで渡された名詞の単語を一度Hashtableに登録し,
これで当初の目的である,
いかがでしたか? 思ってたよりずっと簡単に感じたんではないでしょうか? Map,Reduceのそれぞれの処理での入出力のフォーマットがある程度決まっていることで,
Map,