我想计算两个列表之间的余弦相似度,比如说,列表1是dataSetI,列表2是dataSetII。

假设dataSetI是[3,45,7,2],dataSetII是[2,54,13,15]。列表的长度总是相等的。我想将余弦相似度报告为0到1之间的数。

dataSetI = [3, 45, 7, 2]
dataSetII = [2, 54, 13, 15]

def cosine_similarity(list1, list2):
  # How to?
  pass

print(cosine_similarity(dataSetI, dataSetII))

当前回答

你可以使用SciPy(最简单的方法):

from scipy import spatial

dataSetI = [3, 45, 7, 2]
dataSetII = [2, 54, 13, 15]
print(1 - spatial.distance.cosine(dataSetI, dataSetII))

注意,space .distance.cos()给出了一个不相似度(距离)值,因此要获得相似度,需要从1中减去该值。

另一种解决方法是自己编写函数,甚至考虑不同长度的列表的可能性:

def cosineSimilarity(v1, v2):
  scalarProduct = moduloV1 = moduloV2 = 0

  if len(v1) > len(v2):
    v2.extend(0 for _ in range(len(v1) - len(v2)))
  else:
    v2.extend(0 for _ in range(len(v2) - len(v1)))

  for i in range(len(v1)):
    scalarProduct += v1[i] * v2[i]
    moduloV1 += v1[i] * v1[i]
    moduloV2 += v2[i] * v2[i]

  return round(scalarProduct/(math.sqrt(moduloV1) * math.sqrt(moduloV2)), 3)

dataSetI = [3, 45, 7, 2]
dataSetII = [2, 54, 13, 15]
print(cosineSimilarity(dataSetI, dataSetII))

其他回答

我们可以用简单的数学公式计算余弦相似度。 Cosine_similarity = 1-(向量的点积/向量范数的积)。我们可以定义两个函数分别用于点积和范数的计算。

def dprod(a,b):
    sum=0
    for i in range(len(a)):
        sum+=a[i]*b[i]
    return sum

def norm(a):

    norm=0
    for i in range(len(a)):
    norm+=a[i]**2
    return norm**0.5

    cosine_a_b = 1-(dprod(a,b)/(norm(a)*norm(b)))

使用numpy比较一个数字列表和多个列表(矩阵):

def cosine_similarity(vector,matrix):
   return ( np.sum(vector*matrix,axis=1) / ( np.sqrt(np.sum(matrix**2,axis=1)) * np.sqrt(np.sum(vector**2)) ) )[::-1]

如果你碰巧已经在使用PyTorch,你应该使用他们的cosessimilarity实现。

假设有两个n维的numpy。ndarray, v1和v2,即它们的形状都是(n,)。以下是如何获得它们的余弦相似度:

import torch
import torch.nn as nn

cos = nn.CosineSimilarity()
cos(torch.tensor([v1]), torch.tensor([v2])).item()

或者假设有两个numpy。ndarray w1和w2,它们的形状都是(m, n)。下面给你一个余弦相似度列表,每个都是w1中的一行和w2中的相应行之间的余弦相似度:

cos(torch.tensor(w1), torch.tensor(w2)).tolist()

你可以使用这个简单的函数来计算余弦相似度:

def cosine_similarity(a, b):
  return sum([i*j for i,j in zip(a, b)])/(math.sqrt(sum([i*i for i in a]))* math.sqrt(sum([i*i for i in b])))

你可以在Python中使用简单的函数来实现:

def get_cosine(text1, text2):
  vec1 = text1
  vec2 = text2
  intersection = set(vec1.keys()) & set(vec2.keys())
  numerator = sum([vec1[x] * vec2[x] for x in intersection])
  sum1 = sum([vec1[x]**2 for x in vec1.keys()])
  sum2 = sum([vec2[x]**2 for x in vec2.keys()])
  denominator = math.sqrt(sum1) * math.sqrt(sum2)
  if not denominator:
     return 0.0
  else:
     return round(float(numerator) / denominator, 3)
dataSet1 = [3, 45, 7, 2]
dataSet2 = [2, 54, 13, 15]
get_cosine(dataSet1, dataSet2)