受 this 回答的启发,我试图在经过训练的训练有素的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 ])
答案 0 :(得分:2)
你应该看看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 :(得分:2)
将向量空间模型(即tf-idf和余弦相似度)与布尔模型结合起来可以部分解决这个问题。这些是信息理论的概念,它们在ElasticSearch中使用(并且很好地解释) - 一个非常好的搜索引擎。
这个想法很简单:您将文档存储为反向索引。这与书中最后出现的词语相当,后者提到了他们所提到的页面(文档)。
不是为所有文档计算tf-idf向量,而是仅计算具有至少一个(或指定阈值)单词的文档。这可以简单地通过循环查询文档中的单词,使用倒排索引找到也包含该单词的文档并计算这些单词的相似性来完成。
答案 2 :(得分:1)
对于大型数据集,有一种称为按概念文本聚类的解决方案。搜索引擎使用此技术,
首先,您将文档聚类到某些组(例如50个群集),然后每个群集都有一个代表性文档(其中包含一些包含有关其群集的有用信息的单词)
在第二步,为了计算新文档和您的数据集之间的余弦相似性,您循环遍历所有代表(50个数字)并找到顶部近代表(例如2代表)
在最后一步,您可以遍历所选代表中的所有文档并找到最接近的余弦相似度
使用此技术,您可以减少循环次数并提高性能, 您可以在本书的某些章节中阅读更多tecninc:http://nlp.stanford.edu/IR-book/html/htmledition/irbook.html