2017-01-23 11 views
-1

これは、私の宿題の割り当てに関する2番目の記事で、aprioriアルゴリズムをPythonでコーディングしようとしています - Python - load transaction data into a list of lists, count occurrence of each stringを参照してください。データの読み込みを高速化し、各アイテムがデータセットに表示された回数を数えることができました。私のコードのこの次のセクションは非常にゆっくり実行されています。これらの操作を高速化するためにPython関数を最大限に活用しているわけではありません。ここに私のコードはリストとそれ以前単に使用するために複製コードで作成された辞書で、次のとおりです。Python - タプルのペアを作成する

# a dict and a list that are built earlier 
item_data_lol = [['A B C D E F'], ['A E F G H I J K'], ['A B D E F G H'], ['B C D F G H'], ['G H I K J'], ['G H I J'], ['B C D H J K'], ['B C D H K'], ['A C E G I K'], ['A B D F G H I'], ['A B C D E F G H I J K'], ['A B C D E'], ['C D F G'], ['C E F G H I'], ['C D E J K'], ['J K'], ['G H I J K'], ['A B D'], ['A C D K'], ['A B D I J K'], ['A B C E F G'], ['F G I J K'], ['A F G K'], ['B C E F G H'], ['A D E'], ['A B'], ['C D E F'], ['C E F G H I J'], ['I J K'], ['E F H I J K']] 

first_lookup = collections.Counter(item for line in item_data_lol for item in line[0].split()) 
frequent_items = ['A', 'C', 'B', 'E', 'D', 'G', 'F', 'I', 'H', 'K', 'J'] 

、本質的に、item_data_lolは、文字が買っされている特定の製品を示すトランザクションのリスト、です。私はしばしば一緒に購入される製品のペアを見つけることを試みており、私はfrequent_itemsリストに含まれる製品のペアだけを検討しています。たとえば、最初の取引はA B C D E Fであり、これらの6つの商品がすべて一緒に購入されたことを示しています。ここに私がこれまで持っているものがあります。

# initialize second dict to count frequency of pairs of items 
second_lookup = {} 

# loop over each pair in frequent_tuples, creating a key/value pair in the dict for them 
n = len(frequent_items) 
for i in range(n): 
    for j in range(n): 
     item_1 = frequent_items[i] 
     item_2 = frequent_items[j] 
     if item_1 < item_2: 
      this_key = (item_1, item_2) 
      second_lookup[this_key] = 0 

# loop through each row of the data again, create all possible combinations of pairs 
# check if each pair is a key in second_lookup, if so increment the value by 1 
for line in item_data_lol: 
    line = line[0] 

    # nested for loop over the row, needed to create tuple pairs for all items 
    for item_1 in line.split(): 
     for item_2 in line.split(): 

      # check that the items aren't the same, then created a sorted tuple 
      if item_1 < item_2: 
       test_key = (item_1, item_2) 
       if test_key in second_lookup.keys(): 
        second_lookup[test_key] += 1 

# filter second_lookup down to only those tuples/pairs with > support_threshold count 
frequent_pairs = [] 
for this_key, this_value in second_lookup.iteritems(): 
    if this_value > support_threshold: 
     frequent_pairs.append(this_key) 

私の戦略は単純ですが、遅いです。最初にsecond_lookup辞書を初期化し、frequent_itemsリストに存在する2つのプロダクトのすべての可能なペアに対応する辞書にキーを作成します。 (A、B)、(A、C)、(A、D)となるように、2つのアイテムのすべての組み合わせを作成します。 (A、E)、(A、F)、(B、C)、(B、D)、(B、E)、(B、F)、次に、これらのペアのそれぞれがsecond_lookupディクショナリのキーであるかどうかを確認し、そのキーの値を1だけインクリメントする場合は

です。このプロセスは非常に遅いです。私のテストデータではかなり速い速度で動作しますが、大きなデータセットでは動作しません。どんな考えもありがとう!

EDIT - ifのケースで.keys()を削除したことによるスピードの向上量を過小評価しました。 dict.keys()を呼び出すとき。それだけで問題が解決されたようです。ここで

+2

を意図したとおりに、あなたのコードは作業の順序である場合には、改善を求めてみてくださいここでは:http://codereview.stackexchange.comスタックオーバーフローは、それを修正するために壊れたコードに適しています。 – MooingRawr

+1

この質問はhttp://codereview.stackexchange.comに属しているため、この質問を閉じるには投票しています –

+1

はあなたの以前のQ&Aから覚えていないように聞こえます: 'test_key in second_lookup.keys():' 。 'keys()'を削除してください! –

答えて

0

ので、それを打破するために、しかし醜い

from collections import Counter 
import itertools as it 

c = Counter(it.chain.from_iterable(map(lambda x: it.combinations(x, 2), map(str.split, it.chain.from_iterable(item_data_lol))))) 

似たようなんワンライナーです:

words = it.chain.from_iterable(item_data_lol) 
products_lists = map(str.split, words) 
combinations = map(lambda x: it.combinations(x,2) products_list) 
c = Counter(it.chain.from_iterable(combinations)) 
関連する問題