使用Python计算一组值的余弦距离

4
我的目标是对f列表中的每个值计算余弦相似度(f=[[3492.6], [13756.2], [22442.1], [22361.9], [26896.4]]),通过从列表中取一个值并计算其余下值与它的余弦距离有多接近来计算。因此,结果应该是五个不同的相似度分数。然而,出于某种原因,即使在其他数据集上测试代码,我仍然得到1.0作为余弦相似度。显然,[22361.9][22442.1][13756.2]更相似(就距离而言)。请参见下面的代码;
import numpy.linalg as LA
import numpy as np
import sys

f=[[3492.6], [13756.2], [22442.1], [22361.9], [26896.4]]
cx = lambda a, b : round(np.inner(a, b)/(LA.norm(a)*LA.norm(b)), 2)
for c in f:
     for i in f:
        cosine=cx(c, i)
        print cosine

有什么想法吗?非常感谢您的提前帮助。

你确定不是数据集的问题吗?使用这个链接来检查结果。 - Sukrit Kalra
@SukritKalra,谢谢你的回复。你给我链接的计算余弦的方法没问题,但是一次只能计算两个向量。我有100多个tf-idf权重向量需要同时计算。因此,我创建了一个for循环,但似乎没有准确地工作。 - Tiger1
这就是响应的意思。我检查了你的数据集上的几个值,它们都评估为1。我没有发现你的代码有任何问题,所以我没有将其发布为答案。 :) - Sukrit Kalra
2个回答

0

你的“向量”都是标量,因此它们的余弦相似度都为1.0。你可以将标量视为一维空间中唯一轴上的向量,余弦相似度基于两个向量之间的夹角计算。在一维空间中,“向量”之间的角度始终为0,因此在这种比较方面,所有“向量”都非常相似。

改用多维向量:

f = [ [3492.6, 2134.1],
      [13756.2, 243234.3],
      [22442.1, 23424.0],
      [22361.9, 23482.4],
      [26896.4, 126875.4] ]

输出:

1.0
0.57
0.97
0.97
0.69
0.57
1.0
0.76
0.76
0.99
0.97
0.76
1.0
1.0
0.85
0.97
0.76
1.0
...

这个列表中剩下的1.0值来自于将向量与自身进行比较,因此您可能希望跳过这些值(因为它们总是会得出1.0)。


感谢您的快速回复。我喜欢您提出的多维向量的想法。事实上,f-list 中的每个值都是一个多维向量(我将每个文档中每个唯一术语的向量相加以形成权重向量(多维))。因此,f-list 包含了 5 个多维向量。 - Tiger1

0
问题在于您尝试使用错误的相似度度量。余弦相似度测量两个向量之间的方向相似性。如果它们具有相同的方向,就像您的情况一样,因为它们都是一维的,结果将始终为1。如果您尝试将该公式应用于一维向量,则可以轻松检查此问题。

感谢您的回复。f-list 中的每个值都代表一个文档的 tf-idf 权重向量;换句话说,f-list 包含了 5 个文档。我的理解是,您可以通过它们的 tf-idf 权重(信息检索)计算两个文档之间的余弦相似度,而我已经计算出了它们(即 f-list)。 - Tiger1
据我所理解,你是正确的。这里的问题在于你试图计算文档的相似度,但只考虑了一个术语,这将无法使用余弦相似性。 - papafe
嗨@markusian...这不是一个术语,f-list中的每个值都是一个多维向量(其中文档中的每个术语都是一个向量,并且文档中向量(术语)的总和只是f-list中的一个值)。 - Tiger1
@makusian,我曾经认为余弦距离度量可以与tf-idf一起使用,并且文档中的tf-idf向量通常被加起来形成一个权重向量,余弦相似度度量就是用这个向量进行计算的。 - Tiger1
1
@makusian,非常感谢。现在我清楚了。我不应该总结个体tf-idf向量。 - Tiger1
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接