Python - 使用tf-idf预测新文档的相似度

6

这个 回答的启发,我正在尝试找到训练过的tf-idf向量化器和一个新文档之间的余弦相似度,并返回相似的文档。

下面的代码找到了第一个向量的余弦相似度,而不是一个新的查询。

>>> from sklearn.metrics.pairwise import linear_kernel
>>> cosine_similarities = linear_kernel(tfidf[0:1], tfidf).flatten()
>>> cosine_similarities
array([ 1.        ,  0.04405952,  0.11016969, ...,  0.04433602,
    0.04457106,  0.03293218])

由于我的训练数据非常庞大,循环整个训练向量听起来不是一个好主意。我该如何推断出新文档的向量,并找到相关的文档,就像下面的代码一样?

>>> related_docs_indices = cosine_similarities.argsort()[:-5:-1]
>>> related_docs_indices
array([    0,   958, 10576,  3277])
>>> cosine_similarities[related_docs_indices]
array([ 1.        ,  0.54967926,  0.32902194,  0.2825788 ])

虽然可能有更好的解决方案,但线性搜索并不一定是一个坏主意,如果实现正确,它可以很快。你的数据集有多大?什么查询时间水平是可接受的? - elyase
3个回答

2
这个问题可以通过将向量空间模型(即tf-idf和余弦相似度)与布尔模型结合起来部分解决。这些都是信息论的概念,它们被用于(并且在ElasticSearch中得到了很好的解释)——一个非常好的搜索引擎。
这个想法很简单:将文档存储为倒排索引。这类似于书末的单词,它们持有对它们所提到的页面(文档)的引用。
不需要计算所有文档的tf-idf向量,只需计算至少有一个(或指定阈值)共同单词的文档。这可以通过循环查询文档中的单词,并使用倒排索引找到也包含这个单词的文档,然后计算它们之间的相似度来简单完成。

2
你应该看一下gensim。起始代码示例如下:

请访问gensim


from gensim import corpora, models, similarities

dictionary = corpora.Dictionary(line.lower().split() for line in open('corpus.txt'))
corpus = [dictionary.doc2bow(line.lower().split()) for line in open('corpus.txt')]

tfidf = models.TfidfModel(corpus)
index = similarities.SparseMatrixSimilarity(tfidf[corpus], num_features=12)

在预测时,您首先获取新文档的向量:

doc = "Human computer interaction"
vec_bow = dictionary.doc2bow(doc.lower().split())
vec_tfidf = tfidf[vec_bow]

然后获取相似性(按最相似排序):
sims = index[vec_tfidf] # perform a similarity query against the corpus
print(list(enumerate(sims))) # print (document_number, document_similarity) 2-tuples

这个操作使用了线性扫描,与您的要求相符,但是他们有更优化的实现。如果速度不够快,可以考虑使用近似相似度搜索(Annoy,Falconn,NMSLIB)。


1
谢谢您的回复,我会查看并回复。 - Shlomi Schwartz
我的笔记本死机了。我不知道原因。 - Mehdi Golzadeh

1
对于大数据集,有一种称为“概念文本聚类”的解决方案。搜索引擎使用这种技术。
在第一步,您将文档聚类到一些组中(例如50个簇),然后每个簇都有一个代表性文档(包含一些关于其簇的有用信息的单词)。 在第二步,为了计算新文档与数据集之间的余弦相似度,您需要循环遍历所有代表性(50个数字)并找到最接近的代表性(例如2个代表性)。 在最后一步,您可以循环遍历所选代表性中的所有文档,并找到最接近的余弦相似度。
通过这种技术,您可以减少循环次数并提高性能, 您可以在本书的某些章节中阅读更多技术:http://nlp.stanford.edu/IR-book/html/htmledition/irbook.html

值得说明的是,这只是一种启发式方法,不能保证正确的结果(可能会与“真正”的逐一搜索给出的结果任意偏离)。 - lejlot

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接