首页 > 解决方案 > 如何通过将迭代器传递给 CountVectorizer 来解决内存过载问题?

问题描述

我正在使用CountVectorizer. 我也HashingVectorizer将其视为替代方案,但我认为CountVectorizer这是我需要的,因为它提供了有关文本功能和其他内容的更多信息。

CountVectorizer这里的问题有点常见:拟合模型时我没有足够的内存。

def getTexts():
    # an iterator that will yield each document from the database

vectorizer = CountVectorizer(max_features=500, ngram_range=(1,3))
X = vectorizer.fit_transform(getTexts())

在这里,假设我有一个迭代器,它将一次从数据库中生成一个文档。如果我将此迭代器作为参数传递给CountVectorizer fit()函数,那么词汇表是如何构建的?它是等到完成所有文档的加载然后执行fit()一次,还是一次加载一个文档,进行拟合,然后加载下一个?在这里解决内存开销的可能解决方案是什么?

标签: scikit-learnnlp

解决方案


CountVectorizer会消耗更多内存的原因是CountVectorizer需要在内存中存储一​​个词汇字典,但是HashingVectorizer由于不需要存储词汇字典,因此具有更好的内存性能。Doc of中提到了这两个矢量化器之间的主要区别HashingVectorizer

这种策略有几个优点:

  • 它的内存非常低,可扩展到大型数据集,因为不需要在内存中存储词汇字典
  • 腌制和解除腌制很快,因为它除了构造函数参数之外没有任何状态
  • 它可以用于流式传输(部分拟合)或并行管道,因为在拟合期间没有计算状态。

还有一些缺点(与使用带有内存词汇表的 CountVectorizer 相比):

  • 无法计算逆变换(从特征索引到字符串特征名称),这在尝试反省哪些特征对模型最重要时可能会成为问题。
  • 可能存在冲突:不同的标记可以映射到相同的特征索引。然而在实践中,如果 n_features 足够大(例如文本分类问题为 2 ** 18),这很少会成为问题。
  • 没有 IDF 加权,因为这会使转换器有状态。

当然,它CountVectorizer会一次加载一个文档,进行调整,然后加载下一个。在此过程中,CountVectorizer随着内存使用量的激增,将构建其词汇词典。

要优化内存,您可能需要减小文档数据集的大小,或者提供较低的max_features参数也可能会有所帮助。但是,如果您想彻底解决此内存问题,请尝试使用.HashingVectorizer而不是CountVectorizer.


推荐阅读