天真地实现余弦相似度有什么问题?

时间:2018-12-14 07:50:21

标签: python algorithm nlp

blog post中,我读到以下余弦相似度的“天真的实现”绝不应该在生产中使用,博客文章中没有解释原因,我很好奇,有人可以给出解释吗? / p>

import numpy as np

def cos_sim(a, b):
    """Takes 2 vectors a, b and returns the cosine similarity according 
    to the definition of the dot product
    """
    dot_product = np.dot(a, b)
    norm_a = np.linalg.norm(a)
    norm_b = np.linalg.norm(b)
    return dot_product / (norm_a * norm_b)

# the counts we computed above
sentence_m = np.array([1, 1, 1, 1, 0, 0, 0, 0, 0]) 
sentence_h = np.array([0, 0, 1, 1, 1, 1, 0, 0, 0])
sentence_w = np.array([0, 0, 0, 1, 0, 0, 1, 1, 1])

# We should expect sentence_m and sentence_h to be more similar
print(cos_sim(sentence_m, sentence_h)) # 0.5
print(cos_sim(sentence_m, sentence_w)) # 0.25

3 个答案:

答案 0 :(得分:1)

函数cos_sim应该是应该的。问题是用 counts 表示句子。考虑改用using tf-idf

答案 1 :(得分:0)

有很多充分的理由可以避免这种特殊的实现方式。

对我来说主要的是没有检查0个向量。如果这些向量中的任何一个都为0,则会得到除以0的错误。

另一个原因可能是性能。计算规范要求使用sqrt,这可能会非常昂贵。如果您知道需要多次计算cos_sim,则有必要对向量进行一次归一化,然后使用点积即可。

最后一个原因是执行此操作可能需要专用的硬件支持,而您可能不会使用。就像np.dotnp.linalg.norm会给您带来一些好处,相比于自己实现。

通常,最好使用经过良好测试和良好支持的库。除非您想了解幕后情况(博客文章示例),或者您真的知道自己在做什么。

此问题对计算余弦相似度并可能解决上述问题的库函数有一些建议:Cosine Similarity between 2 Number Lists

答案 2 :(得分:0)

天真一词非常专门用于博客中描述的实现(或者至少我希望如此)。使用余弦相似度没有错。实际上,这是理解文本结构相似性的统计方法,也是经实践证明的方法。结合现代的嵌入方法等,您将拥有更强大的相似框架。

天真,这里更多的是仅使用字数或出现次数来计算相似度