使用 Gensim 将余弦距离缩放为 0-1

Scale cosine distance to 0-1 using Gensim

我已经构建了一个包含大约 3M 文档的 Doc2Vec 模型,现在我想将它与我之前构建的另一个模型进行比较。第二个模型已经缩放到 0-1,所以我现在也想将 gensim 模型缩放到相同的范围,以便它们具有可比性。 这是我第一次使用 gensim,所以我不确定这是如何完成的。没什么特别的,但这是我到目前为止的代码(省略了模型生成代码)。我考虑过缩放(在向量并集中使用 max/min 进行最小最大缩放)推断向量(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

有什么推荐吗?

请注意 'cosine similarity' 和 'cosine distance' 是不同的东西。

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

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

所以:如果函数返回的距离是 similarity,并且现在返回的意外数字超过 1.0,那么您真的不应该调用函数 similarity,这没有错:这在某些模型中是可能的,而不是其他人。

您可以天真地将 0.0 重新调整为 2.0 距离,您的计算将使用 Doc2Vec 向量,使用一些粗糙的锤子,例如:

new_distance = old_distance / 2

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

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

但是余弦相似度可能有很大的不同 maxes/ranges,就像同一个邻居 B 的一个相似度 0.9 但另一个相似度 0.6。他们是相同的文档,并被正确识别为 'most-similar',并且 0.90.6 都不是真正要报告的更差的数字,因为在这两种情况下,正确的最相似的文档位于排行榜的前列。这些模型刚刚结束使用可用坐标 space 的方式有所不同。因此,您不应该将 0.60.9 相似性(或在您的情况下为其他距离数字)与其他模型进行比较 – 尤其是 如果模型使用不同的算法,就像你的情况一样。 (如果看起来您可能正在将字数统计模型的绝对余弦距离与密集学习的 Doc2Vec 模型进行比较。)

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