2016-02-24 86 views
0

今天我刚开始编写一个脚本,它使用gensim库在大型语料库(最少30M句子)上训练LDA模型。 这里是我使用的当前代码:使用gensim库进行内存高效的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) 

运行在一个小语料库这个脚本(2M的句子),我意识到,这大概需要的RAM 7GB。 当我尝试在较大的语料库上运行它时,由于内存问题而失败。 问题显然是由于这样的事实,我现在用这个命令装载文集:

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) 

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

有关此问题及解决方案的任何想法?

回答

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)