2

マッパーから生成された各キーと値のペアの確率を計算しようとしています。

したがって、マッパーが生成するとしましょう:

a, (r, 5)
a, (e, 6)
a, (w, 7)

5+6+7 = 18 を加算してから、確率 5/18、6/18、7/18 を見つける必要があります

レデューサーからの最終的な出力は次のようになります。

a, [[r, 5, 0.278], [e, 6, 0.33], [w, 7, 0.389]]

これまでのところ、リデューサーに値からすべての整数を合計させることしかできません。戻って各インスタンスを合計で割るにはどうすればよいですか?

ありがとう!

4

3 に答える 3

4

上記で行っていることも同様に機能するはずですが、これは単一のキーのすべてのデータがメモリに収まることを前提としています。そうであれば、Reducer ですべての値をメモリに保持し、合計を計算してから、各キーと値のペアの限界値を計算できます。これは一般に「ストライプ」アプローチとして知られています。

ただし、ほとんどの場合、これは当てはまり、データがメモリに収まらない可能性があります。この場合、実際のキーと値のペアの前に値を送信して合計を計算する方法を見つける必要があります。これにより、値を使用して限界値を計算し、すぐに値を発行できるようになります。

これは、「反転順序」設計パターンの候補です。相対頻度を計算する必要がある場合に役立ちます。基本的な考え方は、Mapper の最後で、キーと値のペアの 1 つがすべての値に対して同じ共通キーを持つ各中間データに対して 2 つのキーと値のペアを発行することです。これは、合計を計算するために使用されます。

例:

For a, (r, 5) :
---------------
emit (a, r), 5
emit (a, *), 5


For a, (e, 6) :
---------------
emit (a, e), 6
emit (a, *), 6


For a, (w, 7) :
---------------
emit (a, w), 7
emit (a, *), 7

これが完了したら、キーの最初の値のみを使用して、中間のキーと値のペアのそれぞれを分割するパーティショナーが必要です。上記の例では、「a」を使用しています。

また、キーの 2 番目の部分に常に * を持つキーを配置するキーの並べ替え順序も必要になります。

このようにして、すべての中間キーの最初の部分に「a」があり、同じリデューサーになります。また、以下に示すようにソートされます -

emit (a, *), 5
emit (a, *), 6
emit (a, *), 7
emit (a, e), 6
emit (a, r), 5
emit (a, w), 7

レデューサーでキーと値のペアを反復処理するときに、キーの 2 番目の部分に * がある場合は、キーから値を単純に累積する必要があります。その後、累積値を使用して、他のすべてのキーと値のペアの限界を計算できます。

total = 0
for(value : values){
    if (key.second == *)
        total += value
    else
        emit (key.first , key.second, value, value/total)
}

この設計パターンは、ペア アプローチを使用する順序反転として一般に知られています。このデザイン パターンやその他のデザイン パターンの詳細については、この本の MapReduce デザイン パターンに関する章を読むことをお勧めします - http://lintool.github.com/MapReduceAlgorithms/。例を挙げてとてもよく説明されています。

于 2013-03-25T02:46:11.077 に答える
1

次のように、単純に合計を数え、ペアをメモリに保持して、必要な確率を出すことができます。

reduce (key, list<values>):
    int sum = 0;
    for (value in values) {
        sum = sum + value.frequency; //assuming you can extract two fields in each value: value.word and value.frequency
    }
    String outputValue = "[";
    for (value in values) { //iterate over the values once more
        outputValue = outputValue + "["+ value.word + ", " +value.frequency + ", "+ value.frequency/sum +"],"
    }
    outputValue = outputValue.replaceLast(",","]");
    emit (key, outputValue);

もちろん、私は Python に慣れていないので、これは疑似コードにすぎませんが、移行が非常に簡単になることを願っています。

于 2016-09-21T08:04:20.803 に答える