Diferencia entre la distancia entre pares y X.X + YY – XY ^ t

Imaginemos que tenemos datos como

d1 = np.random.uniform(low=0, high=2, size=(3,2)) d2 = np.random.uniform(low=3, high=5, size=(3,2)) X = np.vstack((d1,d2)) X array([[ 1.4930674 , 1.64890721], [ 0.40456265, 0.62262546], [ 0.86893397, 1.3590808 ], [ 4.04177045, 4.40938126], [ 3.01396153, 4.60005842], [ 3.2144552 , 4.65539323]]) 

Quiero comparar dos métodos para generar las distancias en pares:

asumiendo que X e Y son lo mismo:

 (XY)^2 = XX + YY - 2*XY^t 

Este es el primer método que se usa en scikit-learn para calcular la distancia de pares, y luego para la matriz del núcleo.

 import numpy as np def cal_pdist1(X): Y = X XX = np.einsum('ij,ij->i', X, X)[np.newaxis, :] YY = XX.T distances = -2*np.dot(X, YT) distances += XX distances += YY return(distances) cal_pdist1(X) array([[ 0. , 2.2380968 , 0.47354188, 14.11610424, 11.02241244, 12.00213414], [ 2.2380968 , 0. , 0.75800718, 27.56880003, 22.62893544, 24.15871196], [ 0.47354188, 0.75800718, 0. , 19.37122424, 15.1050792 , 16.36714548], [ 14.11610424, 27.56880003, 19.37122424, 0. , 1.09274896, 0.74497242], [ 11.02241244, 22.62893544, 15.1050792 , 1.09274896, 0. , 0.04325965], [ 12.00213414, 24.15871196, 16.36714548, 0.74497242, 0.04325965, 0. ]]) 

Ahora, si uso la función de distancia de par de scipy como se muestra a continuación, obtengo

 import scipy, scipy.spatial pd_sparse = scipy.spatial.distance.pdist(X, metric='seuclidean') scipy.spatial.distance.squareform(pd_sparse) array([[ 0. , 0.92916653, 0.45646989, 2.29444795, 1.89740167, 2.00059442], [ 0.92916653, 0. , 0.50798432, 3.22211357, 2.78788236, 2.90062103], [ 0.45646989, 0.50798432, 0. , 2.72720831, 2.28001564, 2.39338343], [ 2.29444795, 3.22211357, 2.72720831, 0. , 0.71411943, 0.58399694], [ 1.89740167, 2.78788236, 2.28001564, 0.71411943, 0. , 0.14102567], [ 2.00059442, 2.90062103, 2.39338343, 0.58399694, 0.14102567, 0. ]]) 

¡Los resultados son completamente diferentes! ¿No deberían ser iguales?

Related of "Diferencia entre la distancia entre pares y X.X + YY – XY ^ t"

pdist(..., metric='seuclidean') calcula la distancia euclidiana estandarizada , no la distancia euclidiana al cuadrado (que es lo que devuelve cal_pdist ).

De los documentos :

Y = pdist(X, 'seuclidean', V=None)

Calcula la distancia euclidiana estandarizada. La distancia euclidiana estandarizada entre dos vectores n u y v es

  __________________ √∑(ui−vi)^2 / V[xi] 

V es el vector de varianza; V[i] es la varianza calculada sobre todos los componentes i ‘th de los puntos. Si no se pasa, se computa automáticamente.

Intente pasar metric='sqeuclidean' , y verá que ambas funciones devuelven el mismo resultado dentro del error de redondeo.