Numpy Cosine Similarity difference over big collections
<p>I need to use the Scikit-learn <strong>sklearn.metric.pairwise.cosine_similarity</strong> over big matrixes. 
For some optimizations i need to compute only some rows of the matrixes, and so i tried different methods.</p>

<p>I found that in some cases <strong>the results were different depending on the size of the vectors</strong>, and I saw this strange behaviour on this test case (big vectors, transpose and estimate cosine):</p>

<pre><code>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)
</code></pre>

<p>If "<strong>size</strong>" is set to <strong>200</strong> I got this result, that is ok:</p>

<pre><code>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]
</code></pre>

<p>But if "<strong>size</strong>" is set to <strong>2000</strong> or more, some strange things happen:</p>

<pre><code>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]
</code></pre>

<p>Does anybody know what am I missing?</p>

<p>Thanks in advance</p>

<p>In order to compare <code>numpy.array</code> you have to use <a href="http://docs.scipy.org/doc/numpy/reference/generated/numpy.isclose.html" rel="nofollow"><code>np.isclose</code></a> instead of equality operator. Try:</p>

<pre><code>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))
</code></pre>

<p>The results are:</p>

<pre><code>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]
</code></pre>

<p>as expected.</p>

python numpy scikit-learn cosine-similarity