如何通过将迭代器传递给CountVectorizer解决内存过载?

时间:2019-04-19 07:00:58

标签: scikit-learn nlp

我正在使用CountVectorizer从大量文档(约1500万个文档)中提取文本特征。我还考虑了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(),还是一次加载一个文档,进行拟合,然后再加载下一个文档?有什么可能的解决方案来解决这里的内存开销?

1 个答案:

答案 0 :(得分:1)

CountVectorizer会消耗更多内存的原因是,CountVectorizer需要在内存中存储词汇表,但是HashingVectorizer的内存性能更好,因为它不会需要存储词汇词典。 HashingVectorizer的{​​{3}}中提到了这两个矢量化器之间的主要区别:

  

此策略具有以下优点:

     
      
  • 由于可扩展到大型数据集的内存非常低,因为无需在内存中存储词汇词典
  •   
  • 由于其除了构造函数参数外没有其他任何状态,因此可以快速进行酸洗和腌制
  •   
  • 它可用于流式(部分拟合)或并行管道中,因为在拟合过程中没有计算状态。
  •   
     

还有一些缺点(与使用CountVectorizer和   内存词汇):

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

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

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