2014-08-27 44 views
0

我試圖運行在安然數據語料庫兩字組分析:如何將NLTK計算擴展到多個內核?

for message in messages.find(): 
    sentences = [ s for s in nltk.tokenize.sent_tokenize(message["body"]) ] 
    for sentence in sentences: 
     words = words + PunktWordTokenizer().tokenize(sentence) 
finder = BigramCollocationFinder.from_words(words) 
print finder.nbest(bigram_measures.pmi, 20) 

然而,當我看「頂」,我看到一個核心被飽和,而其他是空閒的。有沒有什麼辦法,我計算分配給所有其他內核(這是對谷歌計算引擎)

頂部輸出:

Tasks: 117 total, 2 running, 115 sleeping, 0 stopped, 0 zombie 
    %Cpu0 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st 
    %Cpu1 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st 
    %Cpu2 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st 
    %Cpu3 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st 
    %Cpu4 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st 
    %Cpu5 :100.0 us, 0.0 sy, 0.0 ni, 0.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st 
    %Cpu6 : 0.3 us, 0.0 sy, 0.0 ni, 99.7 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st 
    %Cpu7 : 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st 
    KiB Mem: 7369132 total, 5303352 used, 2065780 free, 68752 buffers 
    KiB Swap:  0 total,  0 used,  0 free, 4747800 cached 
+0

你的代碼效率很低;在並行化之前(或除此之外),修復它以加快速度:a)'PunctWordTokenizer()'應該只初始化一次,用於每個句子。 b)直接使用'sent_tokenize()'的結果:'在nltk.tokenize.sent_tokenize(...)中使用s:...'。 c)構造安然語料庫中所有單詞的生成器,而不是列表。 – alexis 2014-08-28 11:29:36

+0

謝謝,這很有道理!爲什麼生成器在列表上? – 2014-08-28 12:00:20

+1

一個生成器一次創建並返回一個元素,而一個列表必須全部創建,然後才能繼續下一步。對於大型的語料庫,您可以輕鬆地吹出自己的記憶:請記住,您將每個單詞存儲爲一個字符串,並且Python中的每個字符串都有大約21個字節的開銷,因此您的內存使用量將超過您的語料庫的兩倍。 – alexis 2014-08-29 09:33:48

回答

1

你並不真的需要使用NLTK - 用它用於標記,但你自己寫一個簡單的並行bigram計算函數。您可能需要考慮爲此目的使用內置的mapreduce函數。 Unigram Frequency Calculation示例將解釋這兩個函數的用法。你可以擴展它來計算bigrams。