2

我有一个小程序,它使用 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 这样的文档存储并保持纯粹的 Python 风格。如果有人有一些建议,我将不胜感激。

4

2 回答 2

6

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

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

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

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

于 2012-05-27T13:28:45.790 回答
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())
于 2012-05-27T05:51:29.977 回答