0

以下のコードを並列化すると、attributes 列の要素数が 15 近くあるため、結合に時間がかかります。

combs = set()
for L in range(0,len(attributes)+1):
    combs.add(itertools.combinations(attributes,L))

マルチプロセッシングを使用して並列化する方法はありますか?

これを試しましたが、このエラーが発生しています。- チャンクサイズ <= 0 の場合:

TypeError: 順序付けできない型: range() <= int()

import itertools     
from multiprocessing import Pool
def comb(attributes):
    res = itertools.combinations(attributes)
    return res

def main():
    p = Pool(4)
    times = range(0,len(attributes)+1)                                                
    values = p.map(comb,attributes,times)
    p.close()
    p.join()
    print(values)

if __name__ == '__main__':
    attributes =('Age', 'Workclass', 'Fnlwgt', 'Education', 'Education-num', 'marital-status', 'Occupation', 'Relationship', 'Race', 'Sex', 'Capital-gain', 'Capital-loss', 'Hours-per-week', 'Native country', 'Probability', 'Id')
    main()

質問の説明を求められたので、どうぞ・・・。基本的にn!. たとえば、属性変数に A、B、C がある場合、(A)、(B)、(C)、(A、B)、(A、C)、(A、B、 C)。属性の要素数は静的ではなく、入力データセットに基づいて変化するため、ハードコーディングできません。したがって、ここでは len(attributes) を使用しています。属性はデータセットの属性を格納します。次に、組み合わせを作成するために、 itertools.combinations(attributes,L) は通常、長さ L のすべての組み合わせを作成します。私の例では、長さ (attributes) を指定すると、ABC のみが取得され、他の組み合わせは取得されません。だから私は長さの範囲を作成し、それを1つ追加してゼロ番目の要素に取り組みました。

問題に戻ると、データセットに 15 個の要素が含まれている可能性があるため、長さ (属性) は 15、つまり 15! になります。この階乗を行う必要があるため、この組み合わせの生成には多くの時間がかかります。したがって、各プロセッサが一度に 1 つの組み合わせセットの生成を処理する方法でこれを並列化することを考えています。たとえば、1 つのプロセッサが長さ 2 と長さ 3 のすべての組み合わせを生成します。複数の引数を適切に渡すことができません。これで状況が解決することを願っています。さらに説明が必要な場合はお知らせください。

4

1 に答える 1

4

マルチプロセッシング コードにはいくつかの問題があり、シングル プロセス バージョンのようには機能しません。

まず、p.map適切に呼び出していません。メソッドのmap引数は、呼び出す関数、引数 (単一のシーケンス)、およびワーカーに一度に渡す値の数を指定するチャンク サイズです。rangeオブジェクトを として渡していますchunksize。これがエラーの直接の原因です。

ただし、それを修正しようとすると、他の問題が見つかります。たとえば、属性のリスト全体ではなく、単一の値のみを各ワーカー プロセスに渡すような方法で に渡しますattributesmapそして、comb関数は、値自体ではなく、組み合わせ値に対して反復子を返します (したがって、ワーカーは多かれ少なかれ即座に完了しますが、有用に出力できないものを返します)。

これが私が作業コードであると信じているものです:

import itertools     
from multiprocessing import Pool

# attributes is always accessible as a global, so worker processes can directly access it
attributes = ('Age', 'Workclass', 'Fnlwgt', 'Education', 'Education-num',
              'marital-status', 'Occupation', 'Relationship', 'Race', 'Sex',
              'Capital-gain', 'Capital-loss', 'Hours-per-week', 'Native country',
              'Probability', 'Id')

def comb(n): # the argument n is the number of items to select
    res = list(itertools.combinations(attributes, n)) # create a list from the iterator
    return res

def main():
    p = Pool(4)
    times = range(0, len(attributes)+1)                                                
    values = p.map(comb, times) # pass the range as the sequence of arguments!
    p.close()
    p.join()
    print(values)

if __name__ == '__main__':
    main()

属性のリストが大きい場合、このコードの完了にはまだしばらく時間がかかりますが、それは単純に、出力する値が非常に多いためです (n値を持つセットのパワーセットには2^nサブセットがあります)。私の IDE は、出力が 88000 行を超えていることを教えてくれました (ありがたいことに、すべては表示されませんでした)。問題のマルチプロセッシング部分が出力部分ほど問題にならないとしても、驚くことではありません!

于 2014-09-18T10:43:59.153 に答える