3

特定のクラスの学生のスコアに関するデータが次の形式である

StudentId@CourseId@Marks1@Marks2@Marks3@Marks4@Marks5

01001@104@13@18@25@86@23
01001@106@58@30@10@12@59
01001@108@60@81@97@83@26
01001@110@68@95@11@73@63
01001@112@55@22@74@71@22
01002@104@20@72@76@28@99
01002@106@52@17@20@67@91
01002@108@18@46@61@73@14
01002@110@86@59@50@35@65
01002@112@45@76@97@37@17
.......

5 つの異なる試験で 5 つの異なるコース (5 つの異なるコース ID によって与えられる) で学生が取得したスコアの平均を計算したいと考えています。

上記の私の Map および Reduce クラスは次のとおりです。

public static class Map extends MapReduceBase implements Mapper<LongWritable,Text,Text,DoubleWritable>{
    private Text SID=new Text();
    public void map(LongWritable key, Text value, OutputCollector<Text,DoubleWritable> output,Reporter reporter)throws IOException{
        String data=value.toString();
        String arr[]=data.split("@");
        int i=2;
        double score=0;
        while(i<arr.length){
            score+=Integer.parseInt(arr[i]);
            i++;
        }
        //Dividing The Score to give the average score in a particular course
        score=score/5;
        SID.set(arr[0]);
        output.collect(SID,new DoubleWritable(score));
    }
}

  public static class Reduce extends MapReduceBase implements Reducer<Text,DoubleWritable,Text,DoubleWritable>{
    public void reduce(Text key,Iterator<DoubleWritable> values,OutputCollector<Text,DoubleWritable> output,Reporter reporter)throws IOException{
        double Total=0.0;
        while(values.hasNext()){
            Total+=values.next().get(); 
        }
        //Dividing By 5 to obtain the average score for a particular student
        output.collect(key,new DoubleWritable((Total/5)));              
    }
}

その上、メインクラスでは、他の構成を定義することとは別に、上記のReduceクラスを と クラスの両方としてReducer設定しましたCombiner

しかし、私が得た出力は次のとおりでした

 01001  9.879999999999999
 01002  10.568
 01003  8.712
 01004  10.68
 01005  9.335999999999999
 ....

これは、学生の合計スコアが 25 ではなく 125 で除算されていることを示しています。ただし、クラスscore=score/5からステートメントを削除するMapと、正しい結果が得られました。今私が理解できることから(そしてそれについてはよくわかりません)、それはこの場合ReducerCombinerクラスが同じであるためです。そうですか?Combinerこの場合、クラスはどのように機能しますか?

4

1 に答える 1

3

コンバイナは、マップの実行後に各ノードで実行されます。

それでも、合計の最後でのみ 5 (異なるコースの数) で割る必要があります。したがって、コンバイナーの最後ではなく、リデューサーの最後でのみ分割できます。

基本的に、次のいずれかを実行できます。

  • コンバイナーを取り外します(ただし、レデューサーはそのままにしておきます)
  • レデューサーとまったく同じことを行うが最後に分割しないレデューサーを定義する
于 2013-06-27T14:52:34.560 に答える