我想计算两个列表之间的余弦相似度,比如说,列表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))

当前回答

不使用任何导入

math.sqrt (x)

可以用

x * * 5

如果不使用numpy.dot(),您必须使用列表理解创建自己的dot函数:

def dot(A,B): 
    return (sum(a*b for a,b in zip(A,B)))

然后它只是一个应用余弦相似度公式的简单问题:

def cosine_similarity(a,b):
    return dot(a,b) / ( (dot(a,a) **.5) * (dot(b,b) ** .5) )

其他回答

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

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])))

这里有一个实现,也适用于矩阵。它的行为完全像sklearn余弦相似度:

def cosine_similarity(a, b):    
    return np.divide(
        np.dot(a, b.T),
        np.linalg.norm(
            a,
            axis=1,
            keepdims=True
        ) 
        @ # matrix multiplication
        np.linalg.norm(
            b,
            axis=1,
            keepdims=True
        ).T
    )

符号@代表矩阵乘法。看到 “at”(@)符号在Python中有什么作用?

使用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]

所有答案都非常适合不能使用NumPy的情况。如果可以的话,这里有另一种方法:

def cosine(x, y):
    dot_products = np.dot(x, y.T)
    norm_products = np.linalg.norm(x) * np.linalg.norm(y)
    return dot_products / (norm_products + EPSILON)

还要记住EPSILON = 1e-07,以确保组织安全。

你可以在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)