1
$\begingroup$

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.

$\endgroup$
2
$\begingroup$

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.

$\endgroup$
4
  • $\begingroup$ To reproduce the result of sklearn.metrics.pairwise.euclidean_distances, which numpy method/function should I use for the dot in that formula? $\endgroup$ – czlsws Aug 23 '19 at 16:01
  • $\begingroup$ I'll add it to the answer, since the formatting will be nicer there. $\endgroup$ – Ben Reiniger Aug 24 '19 at 2:32
  • $\begingroup$ Thanks for your detailed answer. Is "coordinate-wise product" same to "Hadamard product"? $\endgroup$ – czlsws Aug 24 '19 at 14:44
  • $\begingroup$ @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"). $\endgroup$ – Ben Reiniger Aug 24 '19 at 15:31

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.