使用 gensim 库进行内存高效 LDA 训练
Memory efficient LDA training using gensim library
今天我刚开始编写一个脚本,使用 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 的内存。
当我尝试在更大的语料库上 运行 它时,由于内存问题,它失败了。
问题显然是由于我正在使用此命令加载语料库:
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)
今天我刚开始编写一个脚本,使用 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 的内存。 当我尝试在更大的语料库上 运行 它时,由于内存问题,它失败了。 问题显然是由于我正在使用此命令加载语料库:
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)