【问题标题】:Numpy Cosine Similarity difference over big collections大集合上的 Numpy 余弦相似度差异
【发布时间】:2017-01-14 22:07:00
【问题描述】:

我需要在大矩阵上使用 Scikit-learn sklearn.metric.pairwise.cosine_similarity。 对于一些优化,我只需要计算矩阵的一些行,所以我尝试了不同的方法。

我发现在某些情况下结果因向量的大小而异,我在这个测试用例(大向量、转置和估计余弦)上看到了这种奇怪的行为: p>

from sklearn.metrics.pairwise import cosine_similarity
from scipy import spatial
import numpy as np
from scipy.sparse import csc_matrix

size=200
a=np.array([[1,0,1,0]]*size)
sparse_a=csc_matrix(a.T)
#standard cosine similarity between the whole transposed matrix, take only the first row
res1=cosine_similarity(a.T,a.T)[0]
#take the row obtained by the multiplication of the first row of the transposed matrix with transposed matrix itself (optimized for the first row calculus only)
res2=cosine_similarity([a.T[0]],a.T)[0]
#sparse matrix implementation with the transposed, which should be faster
res3=cosine_similarity(sparse_a,sparse_a)[0]
print("res1: ",res1)
print("res2: ",res2)
print("res3: ",res3)
print("res1 vs res2: ",res1==res2)
print("res1 vs res3: ",res1==res3)
print("res2 vs res3: ", res2==res3)

如果 "size" 设置为 200 我得到了这个结果,没关系:

res1:  [ 1.  0.  1.  0.]
res2:  [ 1.  0.  1.  0.]
res3:  [ 1.  0.  1.  0.]
res1 vs res2:  [ True  True  True  True]
res1 vs res3:  [ True  True  True  True]
res2 vs res3:  [ True  True  True  True]

但如果“size”设置为2000或更多,就会发生一些奇怪的事情:

res1:  [ 1.  0.  1.  0.]
res2:  [ 1.  0.  1.  0.]
res3:  [ 1.  0.  1.  0.]
res1 vs res2:  [False  True False  True]
res1 vs res3:  [False  True False  True]
res2 vs res3:  [ True  True  True  True]

有人知道我错过了什么吗?

提前致谢

【问题讨论】:

    标签: python numpy scikit-learn cosine-similarity


    【解决方案1】:

    为了比较numpy.array,您必须使用np.isclose 而不是相等运算符。试试:

    from sklearn.metrics.pairwise import cosine_similarity
    from scipy import spatial
    import numpy as np
    from scipy.sparse import csc_matrix
    
    size=2000
    a=np.array([[1,0,1,0]]*size)
    sparse_a=csc_matrix(a.T)
    #standard cosine similarity between the whole transposed matrix, take only the first row
    res1=cosine_similarity(a.T,a.T)[0]
    #take the row obtained by the multiplication of the first row of the transposed matrix with transposed matrix itself (optimized for the first     row calculus only)
    res2=cosine_similarity([a.T[0]],a.T)[0]
    #sparse matrix implementation with the transposed, which should befaster
    res3=cosine_similarity(sparse_a,sparse_a)[0]
    print("res1: ",res1)
    print("res2: ",res2)
    print("res3: ",res3)
    print("res1 vs res2: ", np.isclose(res1, res2))
    print("res1 vs res3: ", np.isclose(res1, res3))
    print("res2 vs res3: ", np.isclose(res2, res2))
    

    结果是:

    res1:  [ 1.  0.  1.  0.]
    res2:  [ 1.  0.  1.  0.]
    res3:  [ 1.  0.  1.  0.]
    res1 vs res2:  [ True  True  True  True]
    res1 vs res3:  [ True  True  True  True]
    res2 vs res3:  [ True  True  True  True]
    

    正如预期的那样。

    【讨论】:

    • 非常感谢您的回答,我运行它并且它有效。但根据文档,np.iscloseto() “返回一个布尔数组,其中两个数组在容差内按元素相等。” 这似乎证实了矩阵中的值并不完全相同(实际上它们在公差范围内彼此接近)。我的问题的重点是为什么 cosine_similarity 在不同的情况下会返回不同的值
    • cosine_similarity 在不同的情况下不会返回不同的值。它总是返回[ 1. 0. 1. 0.]。问题在于比较方式。您不能将==numpy.array 一起使用
    猜你喜欢
    • 2020-02-11
    • 2015-09-30
    • 2020-08-12
    • 2019-05-21
    • 2017-06-13
    • 1970-01-01
    • 2011-01-01
    • 2017-12-12
    相关资源
    最近更新 更多