作为我对另一个答案的评论的续集:是的,缺少词汇会导致问题,至少对我来说是这样。问题是在计算 tf-idf 值(或其他值)时,不考虑不在词汇表中的单词。想象一下,当我们有一个句子“This is karamba”时。并且只有前两个词在词汇表中,然后他们得到更高的分数,因为“karamba”是一个未知词,根本没有得分。因此,“this”和“is”在句子中比“karamba”在词汇表中更重要(请记住,karamba 是我们在这个句子中真正想要查看的唯一词)。
好的,如果语料库中根本没有“karamba”,为什么会有问题呢?因为我们在“this”和“is”非常重要的基础上得到了很多误报,即使它们有点meh。
我是怎么解决的?不方便,但可行。
首先,我按照另一个答案中的建议创建我的语料库词汇。
import copy
from sklearn.feature_extraction.text import TfidfVectorizer
from collections import defaultdict
corpus = []
# Populate the corpus with some data that I have
for d in sorted(os.listdir('d'), key=lambda x: int(x.split('.')[0])):
with open(os.path.join('d', d)) as f:
corpus.append(f.read())
corpus_tfidf_vectorizer = TfidfVectorizer()
corpus_tfidf_matrix = corpus_tfidf_vectorizer.fit_transform(corpus)
corpus_vocabulary = defaultdict(None, copy.deepcopy(corpus_tfidf_vectorizer.vocabulary_))
corpus_vocabulary.default_factory = corpus_vocabulary.__len__
为什么defaultdict
?这是我从里面的词汇创建实现中偷来的一个巧妙的技巧TfidfVectorizer
。如果您想查看它,请检查sklearn.feature_extraction.text.CountVectorizer._count_vocab
. 从本质上讲,它只是一种将单词添加到词汇表中的方法,而无需过多担心正确的索引。
Anywhoo,现在我们开始处理要添加到语料库中的查询。
# Let's say I got a query value from somewhere
query = f.read()
query_vocabulary_vectorizer = TfidfVectorizer()
query_vocabulary_vectorizer.fit_transform([query])
for word in query_vocabulary_vectorizer.vocabulary_.keys():
# Added with proper index if not in vocabulary
corpus_vocabulary[word]
# Nice, everything in the vocabulary now!
query_tfidf_matrix = TfidfVectorizer(vocabulary=corpus_vocabulary).fit_transform([query])
2020 年的注意事项:如果您与 2018 年相比处于相对的未来并且您拥有更新版本的 scipy,则可能不需要此部分。
哦,好吧,现在我们必须合并语料库矩阵。这是有问题的,因为矩阵的大小不再相同。我们必须调整语料库矩阵的大小,因为现在我们(可能)里面有更多的词,如果不使它们大小相同,我们就无法合并它们。有趣和可悲的是,它scipy.sparse
支持调整矩阵大小,但scipy
. 因此,我
从任意提交安装了master
分支: . PS!您需要安装以在您自己的机器中构建(只需)。 scipy
pip install
git+git://github.com/scipy/scipy.git@b8bf38c555223cca0bcc1e0407587c74ff4b3f2e#egg=scipy
cython
scipy
pip install cython
——2018年的我
所以这很麻烦,但现在我们可以愉快地声明:
from scipy import sparse as sp
corpus_tfidf_matrix.resize((corpus_tfidf_matrix.shape[0], query_tfidf_matrix.shape[1]))
# And voilà, we can merge now!
tfidf_matrix = sp.vstack([corpus_tfidf_matrix, query_tfidf_matrix])
巴姆,完成。另一个答案仍然是正确的,我只是在详细说明该解决方案。