python - 0 和 1 之间的余弦相似度
问题描述
我对计算向量之间的相似度很感兴趣,但是这种相似度必须是 0 到 1 之间的数字。关于 tf-idf 和余弦相似度的问题很多,都表明该值介于 0 和 1 之间。来自维基百科:
在信息检索的情况下,两个文档的余弦相似度范围为 0 到 1,因为词频(使用 tf-idf 权重)不能为负。两个词频向量之间的夹角不能大于 90°。
特点是我希望计算来自两个不同 word2vec 模型的两个向量之间的相似性。但是,这些模型已经对齐,因此它们实际上应该在相同的向量空间中表示它们的单词。我可以像这样计算一个单词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 就可以了……但当然,结果值不再是真正的余弦相似度。
这些值不再是真正的全范围角度并不一定重要。(如果算法需要真实角度,它可以使用 -1.0 到 1.0。)
使用无符号绝对值将是一个坏主意,因为它会改变相似性的排名顺序——将一些“天然”最不相似的结果向上移动。
已经有工作限制词向量在维度中只有非负值,通常的好处是结果维度更可能是单独解释的。(参见例如https://cs.cmu.edu/~bmurphy/NNSE/。)但是,gensim 不支持此变体,只有尝试它才能揭示它是否对任何特定项目更好。
此外,还有其他研究表明,通常的词向量在原点周围可能不是“平衡”的(所以你会看到比随机超球面中的点预期的负余弦相似性更少),并且将它们转移到更多平衡通常会改善他们的其他任务。见:https ://arxiv.org/abs/1702.01417v2
推荐阅读
- python - 如何记录 django 视图
- python - 如何在不打开 GUI 的情况下调用 plt.subplots()?
- go - 大摇大摆的一代正在忽略 SecurityDefiniton
- python - Keras Cnn 模型不会提高准确性
- oracle - DBMS_SCHEDULER.CREATE_JOB 返回“未知命令”
- ocaml - ReScript 中的无限列表/流
- asp.net-mvc - MVC 表单需要基于选择
- mysql - 从 MySQL 中的日期列获取每月计数
- swift - 如何在架构 MVC 中安排视图?通过代码编码时
- c++ - 为什么某些程序在前台时,Windows 的 SetCursorPos 无效?