JDi*_*teo 6 python optimization numpy
我有大约 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
Run Code Online (Sandbox Code Playgroud)
以下删除了 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
Run Code Online (Sandbox Code Playgroud)
有没有办法在不丢失最大索引逻辑和正常产品的除法的情况下获得与 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
Run Code Online (Sandbox Code Playgroud)
哈。