繁体   English   中英

python - 以最有效的方式查找两组向量之间的余弦相似度

[英]python - finding cosine similarity between two groups of vectors in the most efficient way

我正在尝试计算两组句子之间的平均余弦相似度。 将句子转换为嵌入后,我需要计算 avg。 以最有效的方式相似。 在这里,我已经尝试过并且花费了时间。 有没有办法改进这个计算?

我还提出了较慢的方法来帮助您理解案例。

X_num 是 pandas.Series 嵌入向量,每行一般为 512、768、1024 或 2048 长。

class1_indexes :属于第 1 类的实例的所有索引。
class2_indexes :属于类 2 的实例的所有索引。

我需要计算类 1 和类 2 的每个向量对之间的余弦相似度。总的来说,我的输出应该是长度为 len(class1_indexes)*len(class2_indexes ) 的余弦相似度向量。
我编辑了包含测试用例的代码,您可以看到这些方法的运行时间如下:

t1 > t2 > t3

第三种方法快 20 倍。 但我正在寻找更快的方法。

提前致谢。

sample_in_each_class = 1000
X_num = pd.Series([np.random.random(10) for i in range(2*sample_in_each_class)])
class1_indexes = list(range(sample_in_each_class))
class2_indexes = list(range(sample_in_each_class,2*sample_in_each_class))

方法1

def cosine_similarity(vec1, vec2):
    norm1 = np.linalg.norm(vec1)
    norm2 = np.linalg.norm(vec2)
    if norm1 == 0:
        norm1 += 0.00001
    if norm2 == 0:
        norm2 += 0.00001  
    return np.dot(vec1, vec2)/(norm1*norm2)
    
approach1 = []
for idx1 in class1_indexes:
    for idx2 in class2_indexes:
        approach1.append(cosine_similarity(X_num.loc[idx1], X_num.loc[idx2]))

方法2

import itertools
vectors_product = itertools.product(X_num[class1_indexes], X_num[class2_indexes])
vectors_product = pd.Series(list(vectors_product))
approach2 = vectors_product.apply(lambda x: cosine_similarity(x[0], x[1]))

方法3

vectors_product = itertools.product(X_num[class1_indexes], X_num[class2_indexes])
vectors_product = np.array(list(vectors_product))
first_part = vectors_product[:,0,:]
second_part = vectors_product[:,1,:]

numerator = np.sum(np.multiply(first_part, second_part), axis=1)
denominator = (np.multiply(np.linalg.norm(first_part, axis=1), 
                           np.linalg.norm(second_part, axis=1)))
approach3 = numerator / denominator
                  

我认为最有效的方法是:

  1. 将您的数据转换为两个 numpy ndarray,每组一个数组。 我假设行是嵌入向量,数组称为 X1 和 X2。
  2. 对每个数组执行X/np.linalg.norm(X, axis=1)
  3. 然后做np.dot(X1, X2.T)
  4. 如果需要,然后展平生成的矩阵。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM