0

私は単純なバイグラム(単語ペア)カウントを試しています。単純な「ペア」アプローチで試しましたが、今は「ストライプ」アプローチを試すように変更しましたが、マッパーのクリーンアップルーチンでは、どういうわけか私のすべてのキーは同じ単語ペアです(最後の単語ペアのように!) と数です。

たとえば、テキスト入力は次のとおりです。

私の名前はフーです。Foo は Hadoop の新機能です。

マッパーでは、ハッシュマップは次のようになります。

((my, name), 1), ((name, is), 1), ((is, foo), 2), ((is, new), 1), ((new, to), 1), ((to, hadoop), 1)

しかし、クリーンアップルーチンで、同じハッシュマップを印刷しようとしましたが、次のようになります

((to, hadoop), 1), ((to, hadoop), 1), ((to, hadoop), 2), ((to, hadoop), 1), ((to, hadoop), 1), ((to, hadoop), 1)

私のコードは次のようになります:

Map Class:
private HashMap<TextPair, Integer> h = new HashMap<TextPair, Integer>();;

void map(...) :
    ...
StringTokenizer itr = new StringTokenizer(value.toString());            
left = itr.nextToken();
while(itr.hasMoreTokens()) {
right = itr.nextToken();

if(left != null && right!= null) {
            **//I have to create new TextPair(key object) each time!** 
    key.set(new Text(left.toLowerCase()), new Text(right.toLowerCase()));
    //If key is there, just do count + 1 else add key with value 1
    if(h.containsKey(key)) {
            int total = h.get(key) + 1;         
        h.put(key, total);
    } else {
        System.out.println("key: "+ key.toString()+ " => 1");                       
        h.put(key, 1);
    }
            //context.write(key, one);
    }
    left = right;
}
    ....

void cleanup(...):
   Iterator<Entry<TextPair, Integer>> itr = h.entrySet().iterator();
   while(itr.hasNext()) {
    Entry<TextPair, Integer> entry = itr.next();
    TextPair key = entry.getKey();
    int total = entry.getValue().intValue();
    System.out.println("--- MAP CLEANUP ---: key: "+ key.toString() + " => Total: "+ total);

    context.write(key, new IntWritable(total));
}
...

注: TextPair は、私のカスタム キー クラスです。なにか提案を?

編集1:

すべてのマップタスクが完了した後、最後に実行されるマップのクリーンアップルーチンはありますか? そして、ハッシュは一種の「グローバル」です。それまたは私のイテレータに何か問題がありますか?

編集2:

ハッシュする前に map() の各反復で新しい TextPair Key オブジェクトを作成する必要があります。私はPythonでハッシュを何度も使用しましたが、それは良いことであり、苦痛ではありません。なぜ毎回新しいオブジェクトを作成する必要があるのか​​ わかりません。

4

2 に答える 2

1

毎回新しいキーを作成するのではなく、再利用しているようです。したがって、どちらの場合も同じ分布が得られ、最初のセットの最後のキーが2番目のセットのすべての場所で使用されます。

于 2012-10-11T04:20:37.660 に答える
0

「Hadoop: The Definitive Guide」の TextPair クラスの例を使用していると思いますか?

問題は、変更可能なオブジェクトを HashMap のキー値として使用するのは安全ではないことです。代わりに、プリミティブのような不変のキーを使用する必要があります。ガイドの TextPair クラスの例は可変であるため、キー オブジェクトを介して値を配置/取得/削除するときに問題が発生する可能性があります。

この問題を回避する 1 つの方法は、既に行ったように、毎回新しい TextPair オブジェクトを作成することです。それを解決する別の方法は、SimpleImmutableEntry クラスを使用することです。

私はあなたと同じ問題に遭遇し、SimpleImmutableEntry のバージョンを実装することで解決しました。

于 2013-03-27T12:52:35.210 に答える