首页 > 解决方案 > 使用 Gensim 将余弦距离缩放到 0-1

问题描述

我已经构建了一个包含大约 3M 文档的 Doc2Vec 模型,现在我想将它与我之前构建的另一个模型进行比较。第二个模型已缩放到 0-1,所以我现在还想将 gensim 模型缩放到相同的范围,以便它们具有可比性。这是我第一次使用 gensim,所以我不确定这是如何完成的。这没什么花哨的,但这是我到目前为止的代码(省略了模型生成代码)。我考虑过对推断向量(v1 和 v2)进行缩放(最小最大缩放与向量联合中的最大/最小值),但我认为这不是正确的方法。这里的想法是比较两个文档(带有可能在语料库中的标记)并输出它们之间的相似度分数。我看过一些 Gensim 的教程,他们经常将单个字符串与语料库的文档进行比较,

 def get_similarity_score(self,string_1, string_2):
    split_tokens1 = string_1.split()
    split_tokens2 = string_2.split()
    v1 = self.model.infer_vector(split_tokens1)
    v2 = self.model.infer_vector(split_tokens2)
    text_score = nltk.cluster.util.cosine_distance(v1, v2)
    return text_score

有什么建议吗?

标签: pythonmathnlptext-mininggensim

解决方案


请注意,“余弦相似度”和“余弦距离”是不同的东西。

余弦相似度的范围可以从-1.01.0——但在某些模型中,例如仅基于正字数的模型,您实际上可能只能看到从0.0到 的值1.0。但在这两种情况下,相似性接近的项目1.0最相似的

另一方面,余弦距离的范围可以从0.02.0,距离为 的项目是距离0.0最小(或最近的)。余弦距离可以大于1.0- 但您可能只在使用密集坐标空间(如 )的模型中看到这样的距离Doc2Vec,而不是在将一半坐标空间留空(所有负坐标)的字数模型中看到。

所以:如果它返回一个距离,你不应该真正调用你的函数similarity,如果它现在返回超过 的惊喜数字1.0,那没有错:这在某些模型中是可能的,但在其他模型中则不然。

您可以天真地重新调整计算将使用向量获得的距离,使用一些粗略的锤子,例如0.02.0Doc2Vec

new_distance = old_distance / 2

但是,请注意,一般而言,来自不同模型的绝对相似性仍然不一定具有有意义的可比性。这甚至在两个不同的Doc2Vec模型之间也是如此。它们的大小受模型元参数等因素的影响很大。

例如,如果您使用完全相同的足够大的文本集来训练一个 100 维Doc2Vec模型和一个 300 维Doc2Vec模型,那么这两个模型可能会非常有用。对于文档 A,它的最近邻居可能始终是文档 B。事实上,它的前 10 个邻居可能非常相似或相同。

但是余弦相似度可能有很大不同的最大值/范围,就像同一个邻居 B0.9在一个但0.6另一个中具有相似性。你是相同的文档,并且被正确地标识为“最相似”,并且两者都不是0.9或者0.6确实不是一个更糟糕的报告数字,因为在这两种情况下,最相似的文档都在排名的顶部。这些模型刚刚以不同的方式使用可用的坐标空间。因此,您不应将其0.60.9相似性(或在您的情况下为其他距离数字)与其他模型进行比较——特别是如果模型使用不同的算法,您似乎就是这种情况。(如果看起来您可能正在将单词计数模型的绝对余弦距离与密集学习的模型进行比较Doc2Vec模型。)

比较模型之间的结果排名可能更有意义。也就是说,忽略原始相似度数,但关心所需文档是否出现在其他文档的前 N ​​个中。或者,也许可以学习一些缩放规则以使距离更具可比性,但是很难做出更具体的建议,甚至很难知道这是否是一个好的步骤,而不知道您在比较模型时的最终目标。


推荐阅读