主题建模内存错误:如何在有大量数据的情况下进行gensim主题建模



我在使用大量数据进行主题建模时遇到了一个问题。我正在尝试进行LDA和NMF主题建模,这是我以前做过的,但没有使用我目前使用的大量数据。主要问题是我不能在创建模型的同时将所有数据保存在内存中。

我需要模型和相关指标。这是我如何使我的模型目前的代码

def make_lda(dictionary, corpus, num_topics):
passes = 3
# Make a index to word dictionary.
temp = dictionary[0]  # This is only to "load" the dictionary.
id2word = dictionary.id2token
model = LdaMulticore(
corpus=corpus,
id2word=id2word,
passes=passes,
num_topics=num_topics
)

return model
def make_nmf(dictionary, corpus, num_topics):

passes = 3
# Make a index to word dictionary.
temp = dictionary[0]  # This is only to "load" the dictionary.
id2word = dictionary.id2token

model = Nmf(
corpus=corpus,
id2word=id2word,
passes=passes,
num_topics=num_topics
)

return model

以下是我如何得到一致性度量和其他一些统计

def get_model_stats(model, model_type, docs, dictionary, corpus, num_topics, verbose=False, get_topics=False):
if model_type == 'lda':
top_topics = model.top_topics(texts=docs, dictionary=dictionary, coherence='c_v') #, num_words=20)
elif model_type == 'nmf':
top_topics = model.top_topics(corpus=corpus, texts=docs, dictionary=dictionary, coherence='c_v') #, num_words=20)
# Average topic coherence is the sum of topic coherences of all topics, divided by the number of topics.
avg_topic_coherence = sum([t[1] for t in top_topics]) / num_topics
rstd_atc = np.std([t[1] for t in top_topics]) / avg_topic_coherence

if verbose:
print('Average topic coherence: ', avg_topic_coherence)
print('Relative Standard Deviation of ATC: ', rstd_atc)

if get_topics:
return avg_topic_coherence, rstd_atc, top_topics

return avg_topic_coherence, rstd_atc

正如你所看到的,我需要我的字典、文本、语料库和id2token对象在不同的时间存储在内存中,有时是同时存储。但我不能那样做,因为像我的短信这样的东西会消耗大量的内存。我的机器就是不够用。

我知道我可以花钱买一台拥有疯狂RAM的虚拟机,但我想知道是否有更好的解决方案。我可以将所有数据存储在磁盘上。如果数据不在内存中,有没有办法运行这些模型?有没有其他解决方案可以让我的记忆力不超负荷?

您没有显示您的corpus(或docs/texts(是如何创建的,但使用Gensim需要记住的一件最重要的事情是,整个训练集基本上不必同时在内存中(就像使用巨大的list一样(。

相反,可以(当内存可能存在问题时,对于任何大型语料库都应该(将其提供为可重复的Python序列,该序列仅根据请求从底层存储中读取单个项目。使用Python生成器通常是这种方法的关键部分(但不是全部(。

Gensim软件包的最初创建者有一篇博客文章,介绍了基本内容:;Python中的数据流:生成器、迭代器、可迭代对象">

您可能会使用一些小的调整,这些调整可能不会产生太大的影响(例如,将列表理解更改为生成器-例如,在求和时(,但这是一个通用的内存节省提示,所以我认为值得一提。

您可以得到的显著差异是在Dictionary上使用一些更激进的修剪。默认参数为prune_at=200000。如果您有大量文档,您可能希望将阈值降低到某个较低的值。

另一件事是将filter_extremes函数应用于创建的词典,以删除不太可能对结果产生影响的单词。在这里,您可以再次更积极地设置参数:

no_below–保留至少包含在no_below中的令牌文件。

no_above–保留包含在不超过no_above中的令牌文档(语料库总大小的一部分,而不是绝对数(。

keep_n–只保留第一个keep_n最频繁的令牌。

除此之外,您可能需要每隔一段时间调用一次垃圾收集器(例如,在运行make_nmf函数之前(:

import gc
gc.collect()

当然,不要并行运行make_nmfmake_lda(您可能没有这样做,但我想强调一下,因为我们没有看到您的整个代码(。

调整这些值可以帮助您减少所需的内存占用,并保持尽可能好的模型。

最新更新