2016-02-24 84 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)