2014-08-27 36 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。