我有大约 30,000 个向量,每个向量有大约 300 个元素。
对于另一个向量(具有相同数量的元素),如何有效地找到最(余弦)相似的向量?
下面是一个使用 python 循环的实现:
from time import time
import numpy as np
vectors = np.load("np_array_of_about_30000_vectors.npy")
target = np.load("single_vector.npy")
print vectors.shape, vectors.dtype # (35196, 312) float3
print target.shape, target.dtype # (312,) float32
start_time = time()
for i, candidate in enumerate(vectors):
similarity = np.dot(candidate, target)/(np.linalg.norm(candidate)*np.linalg.norm(target))
if similarity > max_similarity:
max_similarity = similarity
max_index = i
print "done with loop in %s seconds" % (time() - start_time) # 0.466356039047 seconds
print "Most similar vector to target is index %s with %s" % (max_index, max_similarity) # index 2399 with 0.772758982696
以下删除了 python 循环的速度提高了 44 倍,但不是相同的计算:
print "starting max dot"
start_time = time()
print(np.max(np.dot(vectors, target)))
print "done with max dot in %s seconds" % (time() - start_time) # 0.0105748176575 seconds
有没有办法在不丢失最大索引逻辑和正常产品划分的情况下,使这种与 numpy 相关联的加速进行迭代?为了优化这样的计算,只用 C 语言进行计算是否有意义?
最佳答案
您对于避免循环以获得性能的想法是正确的。您可以使用 argmin
获取最小距离索引。
不过,我会将距离计算更改为 scipy cdist以及。通过这种方式,您可以计算到多个目标的距离,并且可以根据需要从多个距离指标中进行选择。
import numpy as np
from scipy.spatial import distance
distances = distance.cdist([target], vectors, "cosine")[0]
min_index = np.argmin(distances)
min_distance = distances[min_index]
max_similarity = 1 - min_distance
HTH.
关于Python 优化的最余弦相似向量,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/53455909/