# It seems that the output of sklearn.metrics.pairwise.euclidean_distances is different to the formula on doc

The doc of sklearn.metrics.pairwise.euclidean_distances() gives this formula

dist(x, y) = sqrt(dot(x, x) - 2 * dot(x, y) + dot(y, y)).

Apply this formula to this example

X = [[0, 1],
[2, 3]]

Y = [[1, 2],
[3, 4]]

np.dot(X,X) - 2*np.dot(X,Y) + np.dot(Y,Y)


gives this result

array([[ 3,  5],
[-1,  1]])


whilst calling sklearn.metrics.pairwise.euclidean_distances()

euclidean_distances(X , Y, squared = True)


gives

array([[ 2., 18.],
[ 2.,  2.]])


It seems that the output of euclidean_distances() is not consistent to the formula from the doc.

The sklearn docs' formula says it is applying to row vectors $$x$$ and $$y$$. When you call np.dot on the matrices $$X$$ and $$Y$$ it takes the matrix product.

EDIT (responding to question in comments):
It's not straightforward, as the row-vs-row operations needed aren't quite the usual matrix operations. The source code for euclidean_distances does it this way (except that it does lots of input checks, operates on sparse inputs when possible, etc.):

(X*X).sum(axis=1)[:, np.newaxis] - 2*np.dot(X,Y.T) + (Y*Y).sum(axis=1)[np.newaxis, :]


That's not exactly straightforward itself, so I'll say a little more. Say $$X$$ has $$m$$ rows and $$Y$$ has $$n$$ rows. The middle term, by taking $$Y^T$$, gives us a $$m\times n$$ matrix whose $$(i,j)$$-entry is the dot product of the $$i$$th row of $$X$$ with the $$j$$th row of $$Y$$. In the other terms, * on numpy arrays is the coordinate-wise product; summing along rows gives us the rows' squared-norms. The newaxis is a nice trick: casting the first term to now be a $$m\times 1$$ matrix, adding it to the middle term's $$m\times n$$ matrix actually adds it to every column of that matrix (without needing to actually build the matrix of repeated columns of $$X$$'s squared-norms). And of course similarly for the last term: casting to a $$1\times n$$ matrix makes it add to every row of the result.

• To reproduce the result of sklearn.metrics.pairwise.euclidean_distances, which numpy method/function should I use for the dot in that formula? – czlsws Aug 23 '19 at 16:01
• I'll add it to the answer, since the formatting will be nicer there. – Ben Reiniger Aug 24 '19 at 2:32
• Thanks for your detailed answer. Is "coordinate-wise product" same to "Hadamard product"? – czlsws Aug 24 '19 at 14:44
• @czlsws Happy to help. Yes, it is also called the Hadamard product, Schur product, entry-wise product (erm, in fact perhaps "entry-wise" is better than "coordinate-wise"). – Ben Reiniger Aug 24 '19 at 15:31