有人知道如何提取大型数据集的TFIDF向量吗?
Gensim拥有高效的tf-idf模型,不需要一次性将所有内容存储在内存中。
你的语料库只需要是可迭代的,因此无需一次性将整个语料库存储在内存中。
make_wiki脚本根据评论显示,在笔记本电脑上运行维基百科大约需要50分钟。
df.iterrows()
来遍历 df 的行。 - Matt我相信你可以使用 HashingVectorizer
来从文本数据中获取一个较小的 csr_matrix
,然后在其上使用 TfidfTransformer
。存储 800 万行和数万列的稀疏矩阵并不是什么大问题。另一种选择是根本不使用 TF-IDF,也许在没有它的情况下,你的系统可以运行得相当好。
在实践中,您可能需要对数据集进行子采样-有时候,只学习所有可用数据的10%就足够了。这是一个经验性问题,在事先无法确定哪种策略最适合您的任务。在我确信需要800万个文档之前(即在我看到学习曲线上升明显的情况下),我不会担心扩展到800万个文档。
以下是今天早上我正在处理的示例。您可以看到系统的性能随着增加文档而改善,但已经处于一个似乎几乎没有区别的阶段。考虑到训练所需的时间,我认为在500个文件上训练它不值得我的时间。
gensim
即使处理非常大的语料库时也能实现如此小的内存占用的方式。在此处查看教程: http://radimrehurek.com/gensim/tut1.html - mbatchkarov我使用sklearn和pandas解决了这个问题。
使用pandas iterator迭代数据集一次,创建一个单词集合,然后在CountVectorizer词汇中使用它。通过这样做,Count Vectorizer将生成一个具有相同形状的稀疏矩阵列表。现在只需要使用vstack进行分组即可。结果得到的稀疏矩阵与CountVectorizer对象具有相同的信息(但单词顺序不同),并且已适用于所有数据。
如果考虑时间复杂度,这种解决方案并不是最好的选择,但对于内存复杂度而言很不错。我在一个20GB +的数据集上使用了它。
我编写了一个Python代码(不是完整的解决方案),显示了属性,编写了一个生成器或使用pandas块来迭代您的数据集。
from sklearn.feature_extraction.text import CountVectorizer
from scipy.sparse import vstack
# each string is a sample
text_test = [
'good people beauty wrong',
'wrong smile people wrong',
'idea beauty good good',
]
# scikit-learn basic usage
vectorizer = CountVectorizer()
result1 = vectorizer.fit_transform(text_test)
print(vectorizer.inverse_transform(result1))
print(f"First approach:\n {result1}")
# Another solution is
vocabulary = set()
for text in text_test:
for word in text.split():
vocabulary.add(word)
vectorizer = CountVectorizer(vocabulary=vocabulary)
outputs = []
for text in text_test: # use a generator
outputs.append(vectorizer.fit_transform([text]))
result2 = vstack(outputs)
print(vectorizer.inverse_transform(result2))
print(f"Second approach:\n {result2}")
文档长度 公共词项数 词项是否常见或不常见 每个词项出现的次数
HashingVectorizer
从文本数据中获取一个较小的car_matrix
,然后在其上使用TfidfTransformer
。存储一个由800万行和数万列组成的稀疏矩阵并不是什么大问题。 - mbatchkarov