Python 3.x 余弦相似性很慢

Python 3.x 余弦相似性很慢,python-3.x,similarity,cosine-similarity,sentence-similarity,Python 3.x,Similarity,Cosine Similarity,Sentence Similarity,我有一组句子,使用句子编码器将其编码为向量,我想找出与传入查询最相似的句子 搜索功能如下所示: def semantic_search(cleaned_query, data, vectors): query_vec = get_features(cleaned_query)[0].ravel() res = [] for i, d in enumerate(data): qvec = vectors[i].ravel() sim = co

我有一组句子,使用句子编码器将其编码为向量,我想找出与传入查询最相似的句子

搜索功能如下所示:

def semantic_search(cleaned_query, data, vectors):
    query_vec = get_features(cleaned_query)[0].ravel()
    res = []
    for i, d in enumerate(data):
        qvec = vectors[i].ravel()
        sim = cosine_similarity(query_vec, qvec)
        if sim > 0.5:
            res.append((format(sim * 100, '.2f'), data[i]))
    return sorted(res, key=lambda x: x[0], reverse=True)[:15]
import numpy as np
def cosine_similarity(v1, v2):
    mag1 = np.linalg.norm(v1)
    mag2 = np.linalg.norm(v2)
    if (not mag1) or (not mag2):
        return 0
    return np.dot(v1, v2) / (mag1 * mag2)
其中,
cleaned\u query
是一个字符串形式的预处理查询,
data
是一个包含所有句子(总共300个)的列表,
vectors
包含维度数据(300500)中每个句子的编码向量

当我向我的服务发送一个查询时,大约需要10-12秒来处理一个查询,在我看来,这太慢了。我做了一些调试,发现问题出在
cosine\u similarity
函数中,实现如下:

def semantic_search(cleaned_query, data, vectors):
    query_vec = get_features(cleaned_query)[0].ravel()
    res = []
    for i, d in enumerate(data):
        qvec = vectors[i].ravel()
        sim = cosine_similarity(query_vec, qvec)
        if sim > 0.5:
            res.append((format(sim * 100, '.2f'), data[i]))
    return sorted(res, key=lambda x: x[0], reverse=True)[:15]
import numpy as np
def cosine_similarity(v1, v2):
    mag1 = np.linalg.norm(v1)
    mag2 = np.linalg.norm(v2)
    if (not mag1) or (not mag2):
        return 0
    return np.dot(v1, v2) / (mag1 * mag2)
我曾尝试研究过不同的实现,发现一些使用numba-
nb_cosine
的实现非常快,但效果并不好,这意味着上面的
cosine_相似度
可以提供更正确、更有意义的结果。以下是numba的实现:

import numba as nb
import numpy as np
@nb.jit(nopython=True, fastmath=True)
def nb_cosine(x, y):
    xx,yy,xy=0.0,0.0,0.0
    for i in range(len(x)):
        xx+=x[i]*x[i]
        yy+=y[i]*y[i]
        xy+=x[i]*y[i]
    return 1.0-xy/np.sqrt(xx*yy)
有人可以建议,我如何优化我的
余弦\u相似性
函数以更快地工作?这300句话总是一样的。为了以防万一,如果需要,下面是
get\u功能
功能:

def get_features(texts):
    if type(texts) is str:
        texts = [texts]
    with tf.Session(graph=graph) as sess:
        sess.run([tf.global_variables_initializer(), tf.tables_initializer()])
        return sess.run(embed(texts))

我不确定你计算的余弦相似性是否正确 那里您可能需要检查得到的一些值并确保 它们是有道理的

无论如何,加快速度的一种方法是预先计算和存储 300个句子的每个向量的大小,以及 预先计算
query\u vec
的大小。就像现在的代码一样,你是 通过每次调用重新计算每个句子的大小,以及
计算
query\u vec的大小
300次。

谢谢你的建议,我理解你的意思,但这对代码没有任何好处-处理所需的时间几乎相同。真的。我很惊讶,我本以为所有这些重新计算占用了相当大的时间。抱歉,这没用。你可以尝试下面的链接,