文本相似度与 gensim 和余弦相似度

Text similarity with gensim and cosine similarity

from gensim import corpora, models, similarities

documents = ["This is a book about cars, dinosaurs, and fences"]

# remove common words and tokenize
stoplist = set('for a of the and to in - , is'.split())
texts = [[word for word in document.lower().split() if word not in stoplist]
         for document in documents]

# Remove commas
texts[0] = [text.replace(',','') for text in texts[0]]

dictionary = corpora.Dictionary(texts)
corpus = [dictionary.doc2bow(text) for text in texts]

lsi = models.LsiModel(corpus, id2word=dictionary, num_topics=2)

doc = "I like cars and birds"
vec_bow = dictionary.doc2bow(doc.lower().split())

vec_lsi = lsi[vec_bow] 
index = similarities.MatrixSimilarity(lsi[corpus]) 

sims = index[vec_lsi] # perform a similarity query against the corpus
print(sims)

在上面的代码中,我使用余弦相似性技术比较了 "This is a book about cars, dinosaurs, and fences" 与 "I like cars and birds" 的相似程度。

这两个句子实际上有 1 个共同词,即 "cars",但是当我 运行 代码时,我得到它们 100% 相似。这对我来说没有意义。

有人可以建议如何改进我的代码以便我得到一个合理的数字吗?

这些主题建模技术需要各种真实的数据才能获得合理的结果。只有一个或几个文本示例的玩具大小的示例效果不佳——即使它们效果很好,通常也只是运气好或人为的适合性。

特别是:

  • 只有一个示例的模型无法明智地创建多个主题,因为没有文档之间的对比模型

  • 一个模型展示了它以前没有见过的词会忽略这些词,所以你的测试文档看起来和单个词一样'cars'——它以前见过的唯一词

在这种情况下,LSI 将您的单个训练文档和测试文档建模为具有来自第 0 个主题的 0 贡献,以及来自第 1 个主题的积极贡献(不同量级)。由于余弦相似性只比较角度,而不是大小,因此两个文档都沿着同一条线从原点开始,因此没有角度差异,因此相似度为 1.0。

但是如果你有更好的训练数据,并且不仅仅是一个已知单词的测试文档,你可能会开始得到更合理的结果。即使是几十个培训文档和一个带有几个已知单词的测试文档,也可能会有所帮助……但是成百上千或数万个培训文档会更好。