質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.49%
Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

2回答

2607閲覧

pythonでtfidfを並列化

kohekoh

総合スコア140

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2017/07/27 13:43

pythonでtfidfの処理に時間がかかるので、並列処理をしています
しかし、速度が並列化していない処理よりも5秒ほど遅くなるので(並列化していない時は15秒ほど)
cProfileコマンドを用いたところ
普通に実行した際にはでないエラーのようなものがでています

python

1import nltk 2import numpy as np 3import json 4import time 5from multiprocessing import Pool 6import sys 7 8def subcalc(word, collection): 9 subdoc = [] 10 lists = [] 11 wo=[] 12 for term in set(word): 13 if(collection.tf_idf(term, word) > 0): 14 wo.append([term,collection.tf_idf(term, word)]) #ここも上のサイトにのってる 15 wo.sort(key=lambda x:x[1]) #keyに無名関数lambdaをいれてる woの1番目の要素(WO(1,2)だったら”2”)でソート 16 wo.reverse() 17 try: 18 slice1 = np.array(wo[:20]) #先頭の文字から終了インデックスまでが抽出 19 lists = slice1[:,0] #[:]は戦闘から終了のインデックスまで抽出と、slice1の0番目を格納 20 subdoc.append(list(lists)) #listsが文字列だから、リストに格納 21 del wo 22 except: 23 print(wo) 24 return subdoc 25 26def tfidf(): 27 t1 = time.time() 28 doc0 = [] 29 doc = [] 30 word0 = [] 31 word = [] 32 f = open("/Users/uuu/Desktop/Dropbox/prg/dataset/word0_a.txt") #/Users/uuu/Desktop/Dropbox/prg/dataset 33 for row in f: 34 word0.append(row.split("][")) 35 f.close() 36 for i in word0: #word0[0] #普通の時(形態素解析したテキストが改行されてない時) #word0 #改行されてる時 37 word.append(str(i).replace("[","").replace("]","").replace(",","").replace("'","").replace("\"","").split()) 38 #word.pop() 39 ttt = time.time() 40 p = Pool() 41 collection = nltk.TextCollection(word) #サイトにのっていた 42 words = [(i, collection) for i in word] 43 doc = p.starmap(subcalc, words) #複数コアによる実行 44 t3 = time.time() 45 print('processing time2(終わり): ' + str(t3 - ttt) + '(sec)') 46 47if __name__ == "__main__": 48 tfidf() 49 50----------------------------------------------------------------- 51cProfile 実行結果(エラー部分のみ) 52 53Traceback (most recent call last): 54 File "C:\Users\uuu\AppData\Local\conda\conda\envs\anaconda\lib\runpy.py", line 193, in _run_module_as_main 55 "__main__", mod_spec) 56 File "C:\Users\uuu\AppData\Local\conda\conda\envs\anaconda\lib\runpy.py", line 85, in _run_code 57 exec(code, run_globals) 58 File "C:\Users\uuu\AppData\Local\conda\conda\envs\anaconda\lib\cProfile.py", line 160, in <module> 59 main() 60 File "C:\Users\uuu\AppData\Local\conda\conda\envs\anaconda\lib\cProfile.py", line 153, in main 61 runctx(code, globs, None, options.outfile, options.sort) 62 File "C:\Users\uuu\AppData\Local\conda\conda\envs\anaconda\lib\cProfile.py", line 20, in runctx 63 filename, sort) 64 File "C:\Users\uuu\AppData\Local\conda\conda\envs\anaconda\lib\profile.py", line 64, in runctx 65 prof.runctx(statement, globals, locals) 66 File "C:\Users\uuu\AppData\Local\conda\conda\envs\anaconda\lib\cProfile.py", line 100, in runctx 67 exec(cmd, globals, locals) 68 File "tfidf(speedy).py", line 80, in <module> 69 tfidf() 70 File "tfidf(speedy).py", line 66, in tfidf 71 doc = p.starmap(subcalc, words) #複数コアによる実行 72 File "C:\Users\uuu\AppData\Local\conda\conda\envs\anaconda\lib\multiprocessing\pool.py", line 268, in starmap 73 return self._map_async(func, iterable, starmapstar, chunksize).get() 74 File "C:\Users\uuu\AppData\Local\conda\conda\envs\anaconda\lib\multiprocessing\pool.py", line 608, in get 75 raise self._value 76 File "C:\Users\uuu\AppData\Local\conda\conda\envs\anaconda\lib\multiprocessing\pool.py", line 385, in _handle_tasks 77 put(task) 78 File "C:\Users\uuu\AppData\Local\conda\conda\envs\anaconda\lib\multiprocessing\connection.py", line 206, in send 79 self._send_bytes(_ForkingPickler.dumps(obj)) 80 File "C:\Users\uuu\AppData\Local\conda\conda\envs\anaconda\lib\multiprocessing\reduction.py", line 51, in dumps 81 cls(buf, protocol).dump(obj) 82_pickle.PicklingError: Can't pickle <function subcalc at 0x0000016615E9F048>: attribute lookup subcalc on __main__ failed 83

pickle化ができませんというエラーのようなのですが
この部分に速度が速くならない要因があるのでしょうか
あと、対処法があれば教えていただきたいです

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答2

0

ベストアンサー

どうやら multiprocessingを使ってるコードに対して、コマンドラインからcProfileは使用できないみたいですね。

とりあえず、コードに

Python

1if __name__ == "__main__": 2 import cProfile 3 cProfile.run('tfidf()')

のように cProfile を埋め込んでみたください。

投稿2017/07/28 01:38

magichan

総合スコア15898

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

kohekoh

2017/07/28 01:41

できました、ありがとうございます ということはこの処理の遅さとは関係ないということですね…
magichan

2017/07/28 02:05

結果を見る限り、待機時間が多い気がします。 ここからは私の推測ですが、 Poolの場合は結果の順番を保証しておりますので、たとえば4パラで実行ても4つの処理が全て完了しないと次の4つ処理を行えないことになり、1つでも処理時間の長いタスクがあると他の3つが待機となります。 ですので、今回のように「タスクが大量にある」場合、その待ち時間が累積されるため不利に働いているのではないでしょうか。
kohekoh

2017/07/28 02:09

ということは待機時間を減らすしかないということですかね
guest

0

multiprocessingのworkerに渡す関数にpickle化不可能なオブジェクトを渡すことはできません。
https://docs.python.jp/3/library/multiprocessing.html

cProfileをつけた際に発生するエラーなら、適切に計測できていなさそうです。
(例えば、クロージャなどはpickle化できないのですが。そのような値に変換されてmultiprocessingのworkerに渡されてしまっているかもしれません)

投稿2017/07/28 01:13

編集2017/07/28 01:16
podhmo

総合スコア29

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.49%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問