python - 使用 gensim 库进行内存高效 LDA 训练

今天我刚开始编写一个脚本,使用 gensim 库在大型语料库(最少 3000 万个句子)上训练 LDA 模型。 这是我正在使用的当前代码:

from gensim import corpora, models, similarities, matutils

def train_model(fname):
    logging.basicConfig(format='%(asctime)s : %(levelname)s : %(message)s', level=logging.INFO)
    dictionary = corpora.Dictionary(line.lower().split() for line in open(fname))
    print "DOC2BOW"
    corpus = [dictionary.doc2bow(line.lower().split()) for line in open(fname)]

    print "running LDA"
    lda = gensim.models.ldamodel.LdaModel(corpus=corpus, id2word=dictionary, num_topics=100, update_every=1, chunksize=10000, asses=1)

在小型语料库(200 万句)上运行此脚本我意识到它需要大约 7GB 的 RAM。 当我尝试在更大的语料库上运行它时,由于内存问题,它失败了。 问题显然是由于我正在使用此命令加载语料库:

corpus = [dictionary.doc2bow(line.lower().split()) for line in open(fname)]

但是,我认为没有其他方法,因为我需要它来调用 LdaModel() 方法:

lda = gensim.models.ldamodel.LdaModel(corpus=corpus, id2word=dictionary, num_topics=100, update_every=1, chunksize=10000, asses=1)

我搜索了这个问题的解决方案,但找不到任何有用的东西。 我想这应该是一个常见问题,因为我们主要在非常大的语料库(通常是维基百科文档)上训练模型。所以,它应该已经是它的解决方案了。

关于这个问题和解决方案有什么想法吗?

最佳答案

考虑将您的 corpus 包装成一个可迭代对象并传递它而不是列表(生成器将不起作用)。

来自 the tutorial :

class MyCorpus(object):
    def __iter__(self):
       for line in open(fname):
            # assume there's one document per line, tokens separated by whitespace
            yield dictionary.doc2bow(line.lower().split())

corpus = MyCorpus()
lda = gensim.models.ldamodel.LdaModel(corpus=corpus, 
                                      id2word=dictionary,
                                      num_topics=100,
                                      update_every=1,
                                      chunksize=10000,
                                      passes=1)

此外,Gensim 有几种不同的语料库格式,可以在 API reference 中找到。 .您可能会考虑使用 TextCorpus,它应该已经很适合您的格式了:

corpus = gensim.corpora.TextCorpus(fname)
lda = gensim.models.ldamodel.LdaModel(corpus=corpus, 
                                      id2word=corpus.dictionary, # TextCorpus can build the dictionary for you
                                      num_topics=100,
                                      update_every=1,
                                      chunksize=10000,
                                      passes=1)

https://stackoverflow.com/questions/35609171/

相关文章:

php - 匹配 Google adwords 引荐来源网址

loops - 在同一文件中的 gnuplot 中绘制的列

bash - 如何用行缓冲提示包装命令?

php - 我可以在不使用 S3 API 的情况下从我的 Amazon S3 帐户下载文件吗?

Oracle - 带有列表范围分区的 EXCHANGE PARTITION 错误

makefile - 使用 GNU Make 处理带空格的文件名

json - Firebase - 如何使用 curl 编写?

python - 如何在 python 中将对象作为命令行参数传递?

ruby - 如何使用 Chef Recipe 删除文件中的一行?

react-native - React Native 的 Realm - 不区分大小写的搜索