我有一个包含大约800万篇新闻文章的语料库,我需要将它们的TFIDF表示形式作为稀疏矩阵。我已经能够使用scikit-learn获得相对较少数量的样本,但我相信它不能用于如此庞大的数据集,因为它首先将输入矩阵加载到内存中,这是一个昂贵的过程。
有谁知道,提取大型数据集的TFIDF向量的最佳方法是什么?
答案 0 :(得分:21)
gensim有一个高效的tf-idf模型,不需要一次将所有内容都存储在内存中。
http://radimrehurek.com/gensim/intro.html
你的语料库只需要是一个可迭代的,所以它不需要一次将整个语料库放在内存中。
根据评论,make_wiki脚本(https://github.com/piskvorky/gensim/blob/develop/gensim/scripts/make_wikicorpus.py)在笔记本电脑上运行维基百科大约50米。
答案 1 :(得分:10)
我相信您可以使用HashingVectorizer
从文本数据中获取较小的csr_matrix
,然后在其上使用TfidfTransformer
。存储8M行和数万列的稀疏矩阵并不是什么大问题。另一种选择是根本不使用TF-IDF - 如果没有它,你的系统可能会运行得相当好。
在实践中,您可能需要对数据集进行子采样 - 有时系统只需从所有可用数据的10%中学习即可。这是一个经验问题,没有办法事先告诉什么策略最适合您的任务。我不担心扩展到8M文档,直到我确信我需要它们(即直到我看到学习曲线显示出明显的向上趋势)。
以下是我今天上午正在做的事情。随着我添加更多文档,您可以看到系统的性能趋于提高,但它已经处于似乎没什么差别的阶段。考虑到培训需要多长时间,我不认为在500个文件上进行培训是值得的。
答案 2 :(得分:0)
我使用sklearn和pandas解决了这个问题。
使用熊猫iterator在数据集中进行一次迭代,并创建一组所有单词,然后在CountVectorizer词汇表中使用它。这样,Count Vectorizer将生成所有稀疏矩阵的列表,它们的形状均相同。现在只需使用vstack对其进行分组。所得的稀疏矩阵具有与CountVectorizer对象相同的信息(但单词顺序相反),并且适合您的所有数据。
如果考虑时间复杂度,那么该解决方案不是最佳解决方案,但是对于内存复杂度却有好处。我在20GB以上的数据集中使用它,
我编写了一个python代码(没有完整的解决方案),用于显示属性,编写生成器或使用熊猫块在数据集中进行迭代。
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}")
最后,使用TfidfTransformer。
答案 3 :(得分:-1)
文档长度 共有词条数 词条是常见的还是不常见的 每个词条出现的次数