Primero, gracias por leer y tomarse el tiempo para responder.
En segundo lugar, la pregunta:
Tengo una matriz PxN X donde P está en el orden de10 ^ 6 y N es del orden de 10 ^ 3. Entonces, X es relativamente grande y no es escaso. Digamos que cada fila de X es una muestra de N dimensiones. Quiero construir una matriz PxP de distancias en pares entre estas muestras de P. Digamos también que estoy interesado en las distancias de Hellinger.
Hasta ahora estoy confiando en matrices dok dispersas:
def hellinger_distance(X):
P = X.shape[0]
H1 = sp.sparse.dok_matrix((P, P))
for i in xrange(P):
if i%100 == 0:
print i
x1 = X[i]
X2 = X[i:P]
h = np.sqrt(((np.sqrt(x1) - np.sqrt(X2))**2).sum(1)) / math.sqrt(2)
H1[i, i:P] = h
H = H1 + H1.T
return H
Esto es super lento. ¿Hay una manera más eficiente de hacer esto? Cualquier ayuda es muy apreciada.
Respuestas
2 para la respuesta № 1Puedes usar pdist
y squareform
de scipy.spatial.distance
-
from scipy.spatial.distance import pdist, squareform
out = squareform(pdist(np.sqrt(X)))/np.sqrt(2)
O usar cdist
de lo mismo
from scipy.spatial.distance import cdist
sX = np.sqrt(X)
out = cdist(sX,sX)/np.sqrt(2)
1 para la respuesta № 2
Además de la respuesta de Divakar, me di cuenta de que hay una implementación de esto en sklearn que permite el procesamiento paralelo:
from sklearn.metrics.pairwise import pairwise_distances
njobs = 3
H = pairwise_distances(np.sqrt(X), n_jobs=njobs, metric="euclidean") / math.sqrt(2)
Haré una evaluación comparativa y publicaré los resultados más tarde.