2017-11-28 10 views
1

私はカンマ区切りのファイルを多くの列で取り、会社名、顧客とのやりとりの結果、何回起こったのかを調べるプロジェクトがあります。
次に、良好な相互作用に対する悪い相互作用の割合を計算する必要があります 私はHadoopとJavaを使用しています。
私は働くMapとReduceを持っています。会社名と良いやりとりの数がどれほど多いか分かります。Hadoopでパーセンテージを取得する

私の問題は、私がHadoopに良いと悪い分けを分けてもらう方法が見つからないということです。
ほとんどの会社に悪いやりとりはありません。ここで

ここに私のMAPP

public class TermProjectMapper extends Mapper<LongWritable, Text, Text, IntWritable> { 

    private final static IntWritable one = new IntWritable(1); 
    private Text word = new Text(); 

     @Override 
     public void map(LongWritable key, Text value, Context context) 
      throws IOException, InterruptedException { 

      String[] columb = value.toString().split(","); 
      String companyName = columb[5]; 
      String companyResponseToConsumer = columb[12]; 
      String lookfor = "closed without relief"; 

       if (companyResponseToConsumer.toLowerCase().contains(lookfor)) {companyResponseToConsumer="Bad";} 
       else {companyResponseToConsumer="Good";} 
       //System.out.println(companyResponseToConsumer); 
       if (companyName != "" && companyResponseToConsumer != "") 
       { 
        word.set (companyName + " " + companyResponseToConsumer); 
        context.write(word, one); 
       } 
     } 
     } 

public class TermProjectReducer extends Reducer < Text, IntWritable, Text, IntWritable > 
{ 
    private IntWritable result = new IntWritable(); 
     @Override 
     public void reduce(Text key, Iterable <IntWritable> values, Context context) throws IOException, InterruptedException 
     { 
      int sum = 0; 
      for (IntWritable val : values) 
      { 
       sum += val.get(); 
      } 
      if (sum > 0) 
      { 
       result.set(sum); 
       context.write(key, result); 
      } 
     } 
    } 

これは私が今取得しています何の例ですが、私の削減です。

AMERICAN EAGLE MORTGAGE COMPANY,Good, 4 
AMERICAN EQUITY MORTGAGE,Good, 26 
AMERICAN EXPRESS COMPANY,Bad, 250 
AMERICAN EXPRESS COMPANY,Good, 9094 
AMERICAN FEDERAL MORTGAGE CORPORATION,Bad, 1 
AMERICAN FEDERAL MORTGAGE CORPORATION,Good, 3 
AMERICAN FINANCE HOUSE LARIBA,Good, 3 
AMERICAN FINANCIAL MORTGAGE COMPANY,Good, 3 
+0

Textの減速値としてDoubleWritableを使用することをお勧め? –

+0

はい、MapReduceとJavaである必要があります。 – Keg

+0

さて、あなたのレデューサーはちょうど言葉遣いをしています。 「良い」と「悪い」だけのカウントを分離するために何を試みましたか? –

答えて

0

企業を集約するには、それらをキーとして出力してレデューサーで結合する必要があります。言い換えれば、良い値と悪い値の両方を、今行ったように分離するのではなく、同じキーに入れたいとします。

私が最初にあなたが[1, 0][0, 1]を行うことができると思ったが、代わりに("GOOD", 1)("BAD", 1)のちょうど1または-1を出力することに対処するために容易になるだろう。

ので、例えば、

private final static IntWritable ONE = new IntWritable(1); 
private final static IntWritable NEG_ONE = new IntWritable(-1); 

... 

    IntWritable status; 
    if (companyResponseToConsumer.toLowerCase().contains(lookfor)) {status=NEG_ONE;} 
    else {status=ONE;} 

    if (!companyName.isEmpty()) 
    { 
     word.set (companyName); 
     context.write(companyName, status); 
    } 

今、減速中に、カウント値だけでなく、パーセントを計算する(Hadoopのための、より効率的なデータ転送)。

public class TermProjectReducer extends Reducer < Text, IntWritable, Text, IntWritable > 
{ 
    private IntWritable result = new IntWritable(); 

    @Override 
    public void reduce(Text key, Iterable <IntWritable> values, Context context) throws IOException, InterruptedException 
    { 
     int total = 0; 
     int good_sum = 0; 
     for (IntWritable val : values) 
     { 
      good_sum += (val.get() == 1 ? 1 : 0); 
      total += 1 
     } 
     if (total > 0) // Prevent division by zero 
     { 
      double percent = 1.0*good_sum/total; 
      // Round it to how every many decimal places, if you want 
      result.set(String.valueOf(percent)); // convert the floating number to a string 
     } else { 
      result.set("0.00"); 
     } 
     context.write(key, result); 
    } 
} 

そして、あなたの下流の処理中にあなたが(1 - good) = badを自分で行うことができますので、私は唯一の良い値を算出しました。

また、私はそれがMapReduceの代わりのハイブ/スパーク/ピッグする必要がない代わりに

+0

ありがとうございましたcricket_007それでした。一緒に仕事をするのにはちょっと時間がかかりましたが、あなたは私を正しい道に導きました!ありがとうございました! – Keg

関連する問題