Python NLTK FreqDist()通过将k,v写入磁盘来减少内存使用量?

时间:2012-05-27 03:55:23

标签: python key nltk frequency-distribution

我有一个小程序,它使用NLTK来获取相当大的数据集的频率分布。问题是,几百万字后,我开始吃掉我系统上的所有RAM。以下是我认为相关的代码行:

freq_distribution = nltk.FreqDist(filtered_words)               # get the frequency distribution of all the words
top_words = freq_distribution.keys()[:10]                       # get the top used words
bottom_words = freq_distribution.keys()[-10:]                   # get the least used words

必须有办法将密钥,值存储写入磁盘,我只是不确定如何。我试图远离像MongoDB这样的文档存储,并保持纯粹的pythonic。如果有人有一些建议我会很感激。

2 个答案:

答案 0 :(得分:6)

巧合的是,过去一个月我遇到了同样的问题。我试图使用NLTK和FreqDist从大型数据集(例如英语维基百科和古腾堡数据集)创建n-gram频率表。我的8GB机器可以在内存中存储一​​个unigram模型,但不是一个二元模型。

我的解决方案是使用BerkeleyDB,它将k,v数据库存储到磁盘;但也存储内存表缓存以提高速度。对于频率分布,这非常慢,所以我还使用FreqDist在内存中创建了自己的子表,然后定期将它们保存到BerkeleyDB(通常每1000个左右的输入文件)。这大大减少了BerkeleyDB写入,因为它删除了大量重复项 - 例如。 unigram模型中的“the”只写一次而不是多次100,0000次。我在这里写了:

https://www.winwaed.com/blog/2012/05/17/using-berkeleydb-to-create-a-large-n-gram-table/

使用pickle的问题是你必须将整个发行版存储在内存中。纯粹pythonic的唯一方法是编写自己的实现,使用它自己的k,v磁盘数据库,可能还有你自己的内存缓存。使用BerkeleyDB非常简单,高效!

答案 1 :(得分:2)

我已经使用JSON模块在​​这些情况下存储大型词典(或其他数据结构)。我认为picklecpickle可能更有效,除非您想以人类可读的形式存储数据(通常对nlp有用)。

我是这样做的:

import json
d = {'key': 'val'}
with open('file.txt', 'w') as f:
    json.dump(d, f)

然后检索,

with open('file.txt', 'r') as f:
    d = json.loads(f.read())