6

Google I / O2010のAppEngineセッションでバッチデータ処理を見て、Google ResearchのMapReduce記事の一部を読んだところ、GoogleAppEngineでMapReduceを使用してPythonでレコメンダーシステムを実装することを考えています。

Task Queue APIの代わりにappengine-mapreduceを使用することをお勧めします。前者は、ある種のすべてのインスタンス、自動バッチ処理、自動タスクチェーンなどを簡単に反復できるためです。問題は、レコメンダーシステムが2つの異なるモデルのインスタンス間の相関を計算する必要があることです。つまり、2つの異なる種類のインスタンスです。

例:ユーザーとアイテムの2つのモデルがあります。それぞれに属性としてタグのリストがあります。以下は、ユーザーとアイテム間の相関を計算するための関数です。calculateCorrelationユーザーとアイテムのすべての組み合わせに対して呼び出す必要があることに注意してください。

def calculateCorrelation(user, item):
    return calculateCorrelationAverage(u.tags, i.tags)

def calculateCorrelationAverage(tags1, tags2):
    correlationSum = 0.0
    for (tag1, tag2) in allCombinations(tags1, tags2):
        correlationSum += correlation(tag1, tag2)
    return correlationSum / (len(tags1) + len(tags2))

def allCombinations(list1, list2):
    combinations = []
    for x in list1:
        for y in list2:
            combinations.append((x, y))
    return combinations             

しかし、それcalculateCorrelationはappengine-mapreduceの有効なマッパーではなく、おそらくこの関数はMapReduce計算の概念と互換性さえありません。それでも、私は確信する必要があります...自動バッチ処理やタスクチェーンなどのappengine-mapreduceの利点があることは私にとって本当に素晴らしいことです。

そのための解決策はありますか?

独自のInputReaderを定義する必要がありますか?2つの異なる種類のすべてのインスタンスを読み取る新しいInputReaderは、現在のappengine-mapreduce実装と互換性がありますか?

または、次のことを試してみるべきですか?

  • これら2種類のすべてのエンティティのすべてのキーを2つずつ組み合わせて新しいモデルのインスタンスにします(おそらくMapReduceを使用)
  • この新しいモデルのインスタンスに対してマッパーを使用して反復します
  • インスタンスごとに、その中のキーを使用して、異なる種類の2つのエンティティを取得し、それらの間の相関を計算します。
4

2 に答える 2

3

Nick Johnsonの提案に従って、私は自分のInputReaderを作成しました。このリーダーは、2つの異なる種類からエンティティをフェッチします。これらのエンティティのすべての組み合わせを持つタプルが生成されます。ここにあります:

class TwoKindsInputReader(InputReader):
    _APP_PARAM = "_app"
    _KIND1_PARAM = "kind1"
    _KIND2_PARAM = "kind2"
    MAPPER_PARAMS = "mapper_params"

    def __init__(self, reader1, reader2):
        self._reader1 = reader1
        self._reader2 = reader2

    def __iter__(self):
        for u in self._reader1:
            for e in self._reader2:
                yield (u, e)

    @classmethod
    def from_json(cls, input_shard_state):
        reader1 = DatastoreInputReader.from_json(input_shard_state[cls._KIND1_PARAM])
        reader2 = DatastoreInputReader.from_json(input_shard_state[cls._KIND2_PARAM])

        return cls(reader1, reader2)

    def to_json(self):
        json_dict = {}
        json_dict[self._KIND1_PARAM] = self._reader1.to_json()
        json_dict[self._KIND2_PARAM] = self._reader2.to_json()
        return json_dict

    @classmethod
    def split_input(cls, mapper_spec):
        params = mapper_spec.params
        app = params.get(cls._APP_PARAM)
        kind1 = params.get(cls._KIND1_PARAM)
        kind2 = params.get(cls._KIND2_PARAM)
        shard_count = mapper_spec.shard_count
        shard_count_sqrt = int(math.sqrt(shard_count))

        splitted1 = DatastoreInputReader._split_input_from_params(app, kind1, params, shard_count_sqrt)
        splitted2 = DatastoreInputReader._split_input_from_params(app, kind2, params, shard_count_sqrt)
        inputs = []

        for u in splitted1:
            for e in splitted2:
                inputs.append(TwoKindsInputReader(u, e))

        #mapper_spec.shard_count = len(inputs) #uncomment this in case of "Incorrect number of shard states" (at line 408 in handlers.py)
        return inputs

    @classmethod
    def validate(cls, mapper_spec):
        return True #TODO

このコードは、2種類のエンティティのすべての組み合わせを処理する必要がある場合に使用する必要があります。これを2種類以上に一般化することもできます。

ここでそれは有効なmapreduce.yamlですTwoKindsInputReader

mapreduce:
- name: recommendationMapReduce
  mapper:
    input_reader: customInputReaders.TwoKindsInputReader
    handler: recommendation.calculateCorrelationHandler
    params:
    - name: kind1
      default: kinds.User
    - name: kind2
      default: kinds.Item
    - name: shard_count
      default: 16
于 2010-10-20T13:38:48.540 に答える
2

実際に計算しているものの詳細がなければ、何を推奨するかを知ることは困難です。簡単なオプションの1つは、マップ呼び出し内の関連エンティティをフェッチすることです。そこでデータストア操作を実行することを妨げるものは何もありません。

ただし、これにより多くの小さな呼び出しが発生します。ご提案のとおり、カスタムInputReaderを作成すると、両方のエンティティセットを並行してフェッチできるようになり、パフォーマンスが大幅に向上します。

これらのエンティティに参加する方法について詳しく説明していただければ、より具体的な提案を提供できる可能性があります。

于 2010-09-22T12:27:38.413 に答える