我正在使用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()
,还是一次加载一个文档,进行拟合,然后再加载下一个文档?有什么可能的解决方案来解决这里的内存开销?
答案 0 :(得分:1)
CountVectorizer
会消耗更多内存的原因是,CountVectorizer
需要在内存中存储词汇表,但是HashingVectorizer
的内存性能更好,因为它不会需要存储词汇词典。 HashingVectorizer
的{{3}}中提到了这两个矢量化器之间的主要区别:
此策略具有以下优点:
- 由于可扩展到大型数据集的内存非常低,因为无需在内存中存储词汇词典
- 由于其除了构造函数参数外没有其他任何状态,因此可以快速进行酸洗和腌制
- 它可用于流式(部分拟合)或并行管道中,因为在拟合过程中没有计算状态。
还有一些缺点(与使用CountVectorizer和 内存词汇):
- 无法计算逆变换(从特征索引到字符串特征名称),这在尝试进行逆变换时可能会出现问题 反思哪些特征对模型最重要。
- 可能会发生冲突:不同的标记可以映射到相同的特征索引。但是在实践中,如果 n_features足够大(例如2 ** 18用于文本分类 问题)。
- 没有IDF加权,因为这会使转换器处于有状态。
当然,CountVectorizer
会一次加载一个文档,进行调整,然后加载下一个文档。在此过程中,CountVectorizer
将随着内存使用量的激增建立其词汇词典。
要优化内存,您可能需要减小文档数据集的大小,或者提供较小的max_features
参数也可能会有所帮助。但是,如果您想彻底解决此内存问题,请尝试使用HashingVectorizer
而不是CountVectorizer
。