【问题标题】:efficient way of constructing a matrix of pair-wise distances between many vectors?在许多向量之间构建成对距离矩阵的有效方法?
【发布时间】:2015-10-07 17:34:29
【问题描述】:

首先,感谢您阅读并花时间回复。

二、问题:

我有一个 PxN 矩阵 X,其中 P 大约为 10^6,N 大约为 10^3。所以,X 比较大,而且不是稀疏的。假设 X 的每一行都是一个 N 维样本。我想在这些 P 个样本之间构建一个成对距离的 PxP 矩阵。假设我对 Hellinger 距离感兴趣。

到目前为止,我依赖于稀疏的 dok 矩阵:

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

这太慢了。有没有更有效的方法来做到这一点?非常感谢任何帮助。

【问题讨论】:

  • 真的需要计算每对距离吗?您的 PxP 矩阵将包含 1E12 个元素,因此假设您正在处理双浮点数,您正在查看大约 8000 GB 来存储输出。如果您只是计算上三角形,那将是 (P^2 - P) / 2 ~= 5E11 元素,假设双浮点数约为 4000 GB。即使是这种大小的二进制矩阵,大小也大约为 500 GB。
  • 你是对的。我了解到,使用 scipy 中的密集矩阵,您可以直接计算压缩形式(仅限上三角),但不能使用稀疏矩阵。

标签: python numpy scipy memory-efficient scalable


【解决方案1】:

您可以从scipy.spatial.distance 使用pdistsquareform -

from scipy.spatial.distance import pdist, squareform

out = squareform(pdist(np.sqrt(X)))/np.sqrt(2)

或者使用相同的cdist -

from scipy.spatial.distance import cdist

sX = np.sqrt(X)
out = cdist(sX,sX)/np.sqrt(2)

【讨论】:

  • 感谢您快速而干净的回复。我还在运行这个,计算还没有完成。我会在得到结果后更新。
  • @JRun 太棒了!让我知道这是怎么回事!以及性能提升(希望有一些!)。
【解决方案2】:

除了 Divakar 的回应,我意识到在 sklearn 中有一个实现,它允许并行处理:

from sklearn.metrics.pairwise import pairwise_distances
njobs = 3
H = pairwise_distances(np.sqrt(X), n_jobs=njobs, metric='euclidean') / math.sqrt(2)

我会做一些基准测试并稍后发布结果。

【讨论】:

  • 很高兴看到替代品,很好!
猜你喜欢
  • 2020-03-13
  • 2012-12-21
  • 1970-01-01
  • 2018-06-19
  • 1970-01-01
  • 1970-01-01
  • 2018-11-30
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多