0 和 1 之间的余弦相似度

Cosine similarity between 0 and 1

我对计算向量之间的相似度很感兴趣,但是这个相似度必须是0到1之间的一个数。关于tf-idf和余弦相似度的问题有很多,都表明值在0到1之间。来自 Wikipedia:

In the case of information retrieval, the cosine similarity of two documents will range from 0 to 1, since the term frequencies (using tf–idf weights) cannot be negative. The angle between two term frequency vectors cannot be greater than 90°.

特别之处在于我希望计算来自两个不同word2vec 模型的两个向量之间的相似度。不过,这些模型已经对齐,所以它们实际上应该在同一个向量中表示它们的词 space。我可以像这样计算 model_a 中的单词和 model_b 中的单词之间的相似度

import gensim as gs
from sklearn.metrics.pairwise import cosine_similarity

model_a = gs.models.KeyedVectors.load_word2vec_format(model_a_path, binary=False)
model_b = gs.models.KeyedVectors.load_word2vec_format(model_b_path, binary=False)

vector_a = model_a[word_a].reshape(1, -1)
vector_b = model_b[word_b].reshape(1, -1)

sim = cosine_similarity(vector_a, vector_b).item(0)

但是 sim 是 [-1,1] 范围内的相似性度量。是否有科学合理的方法将其映射到 [0,1] 范围?直觉上我会认为

norm_sim = (sim + 1) / 2

没问题,但我不确定就余弦相似度的实际含义而言,这是否是一种好的做法。如果不是,是否建议使用其他相似性指标?

我试图让值介于 0 和 1 之间的原因是因为数据将被传输给一位同事,她将把它用作她的机器学习系统的一个特征,该系统期望所有值都是在 0 和 1 之间。她的直觉是取绝对值,但在我看来这是一个更糟糕的选择,因为这样你就可以将对立面映射为相同。不过,考虑到余弦相似度的实际含义,我可能是错的。所以如果取绝对值是好的方法,我们也可以这样做。

您有充分的理由更喜欢 0.0-1.0(尽管许多学习算法应该在 -1.0 到 1.0 的范围内表现良好)。如果您的唯一目的是获得 0.0-1.0 范围,您的 norm_sim 重新缩放 -1.0 到 1.0 到 0.0 到 1.0 没问题......但是当然结果值不再是真实的 cosine-similarity .

这些值不再是真实的 full-range 角度并不一定重要。 (如果算法需要真实角度,它可以使用 -1.0 到 1.0。)

使用无符号的绝对值不是一个好主意,因为它会改变相似性的排名顺序——将一些 "natively" most-dissimilar 的结果向上移动。

一直在努力将 word-vectors 限制在维度中只有 non-negative 个值,通常的好处是生成的维度更有可能被单独解释。 (参见示例 https://cs.cmu.edu/~bmurphy/NNSE/。)但是,gensim 不支持此变体,只有尝试它才能揭示它是否对任何特定项目更好。

此外,还有其他研究表明通常的 word-vectors 可能不在原点附近 'balanced'(所以你会看到比从随机超球体),并且将它们移动到更加平衡通常会改进它们以用于其他任务。参见:https://arxiv.org/abs/1702.01417v2

只是对@gojomo 的回答的更新,我认为你需要有可解释的词嵌入,其中包含 非负 维度值(与提出的原始 word2vec 模型相反)米科洛夫等人)。从这个意义上说,您将能够根据需要使用 0-1 之间的余弦相似度来获得单词相似度。

这篇论文很好地解决了这个问题:https://www.aclweb.org/anthology/D15-1196