python - 使用 numba 计算向量和矩阵行之间的余弦相似度

标签 python numpy vector numba numba-pro

找到这个 gist使用 numba 快速计算余弦相似度。

import numba

@numba.jit(target='cpu', nopython=True)
def fast_cosine(u, v):
    m = u.shape[0]
    udotv = 0
    u_norm = 0
    v_norm = 0
    for i in range(m):
        if (np.isnan(u[i])) or (np.isnan(v[i])):
            continue

        udotv += u[i] * v[i]
        u_norm += u[i] * u[i]
        v_norm += v[i] * v[i]

    u_norm = np.sqrt(u_norm)
    v_norm = np.sqrt(v_norm)

    if (u_norm == 0) or (v_norm == 0):
        ratio = 1.0
    else:
        ratio = udotv / (u_norm * v_norm)
    return ratio

结果看起来很有希望(500ns 对比只有 200us,我的机器没有 jit decorator)。

我想使用 numba 来并行化向量 u 和候选矩阵 M 之间的计算——即每一行的余弦.

例子:

def fast_cosine_matrix(u, M):
    """
    Return array of cosine similarity between u and rows in M
    >>> import numpy as np
    >>> u = np.random.rand(100)
    >>> M = np.random.rand(10, 100)
    >>> fast_cosine_matrix(u, M)
    """

一种方法是用第二个输入重写一个矩阵。但是如果我尝试遍历矩阵的行,我会得到一个 NotImplementedError。打算尝试只使用切片。

我考虑过使用 vectorize,但我无法让它工作。

最佳答案

稍微重写一下的解决方案:

import numpy as np
import numba

@numba.jit(target='cpu', nopython=True, parallel=True)
def fast_cosine_matrix(u, M):
    scores = np.zeros(M.shape[0])
    for i in numba.prange(M.shape[0]):
        v = M[i]
        m = u.shape[0]
        udotv = 0
        u_norm = 0
        v_norm = 0
        for j in range(m):
            if (np.isnan(u[j])) or (np.isnan(v[j])):
                continue

            udotv += u[j] * v[j]
            u_norm += u[j] * u[j]
            v_norm += v[j] * v[j]

        u_norm = np.sqrt(u_norm)
        v_norm = np.sqrt(v_norm)

        if (u_norm == 0) or (v_norm == 0):
            ratio = 1.0
        else:
            ratio = udotv / (u_norm * v_norm)
        scores[i] = ratio
    return scores


u = np.random.rand(100)
M = np.random.rand(100000, 100)

fast_cosine_matrix(u, M)

关于python - 使用 numba 计算向量和矩阵行之间的余弦相似度,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/47315659/

相关文章:

python - python中的矩形脉冲序列

python - 如果以下代码调用 np.sum() 如何减少数量?(测试规则规定只能进行 2 次调用)

Python:从多个文件读取数据到二维numpy数组或列表的方法

c++ - vector<double>::size_type 与 double

vector - 对于每个结构都包含结构数组子集的结构向量,正确的模式是什么?

C++ 在同一个程序中使用不同的代码来处理 vector 和列表的排序

Python:使用 lxml + objectify + findall 或 fromstring 获取特定节点值和属性

python - Django:值错误。 View 未返回 HTTPResponseObject

python asyncore跟不上高数据率

python - 消除 python 列表中的 n 个最高值