python - 使用 numpy 方法计算核矩阵

标签 python numpy array-broadcasting

我有一个形状为 d X N 的数据(每列都是特征向量) 我有这个计算内核矩阵的代码:

def kernel(x1, x2):
  return x1.T @ x2

data = np.array([[1,2,3], [1,2,3], [1,2,3]])
result = []
for i in range(data.shape[1]):
  current_result = []
  for j in range(data.shape[1]):
    x1 = data[:, i]
    x2 = data[:, j]
    current_result.append(kernel(x1, x2))
  result.append(current_result)

np.array(result)

我得到了这个结果:

array([[ 3,  6,  9],
       [ 6, 12, 18],
       [ 9, 18, 27]])

问题是这段代码太慢了,所以我尝试使用np.vectorize:

vec = np.vectorize(kernel, signature='(n),(n)->()')
vec(data, data)

但是我得到了错误的结果:

array([14, 14, 14])

我做错了什么?

最佳答案

当测试问题的更大维度和随机数以确保稳健性时,例如维度 (100,200),有几种方法:

import numpy as np

def kernel(x1, x2):
    return x1.T @ x2

def kernel_kenny(a):
    result = []
    for i in range(a.shape[1]):
      current_result = []
      for j in range(a.shape[1]):
        x1 = a[:, i]
        x2 = a[:, j]
        current_result.append(kernel(x1, x2))
    
      result.append(current_result)

    return np.array(result)

a = np.random.random((100,200))

res1 = kernel_kenny(a)

# perhaps einsum signature might help you to understand the calculations
res2 = np.einsum('ji,jk->ik', a, a, optimize=True)
# or the following if you want to explicitly specify the transpose
# res2 = np.einsum('ij,jk->ik', a.T, a, optimize=True)
    
# or simply ...
res3 = a.T @ a

Hera 进行健全性检查:

np.allclose(res1,res2)
>>> True

np.allclose(res1,res3)
>>> True

及时间安排:

%timeit kernel_kenny(a)
>>> 83.2 ms ± 425 µs per loop (mean ± std. dev. of 7 runs, 10 loops each)

%timeit np.einsum('ji,jk->ik', a, a, optimize=True)
>>> 325 µs ± 4.15 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)

%timeit a.T @ a
>>> 82 µs ± 9.39 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)

关于python - 使用 numpy 方法计算核矩阵,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/67517122/

相关文章:

python - 将 groupby 数据框 reshape 为固定尺寸

python - 为什么 pandas 在 `apply` 中对这两个字符串的处理方式不同?

python - 子进程中 `shell` 中的 `shell=True` 是否表示 `bash` ?

python - 压缩 Conda 环境破坏 Audioread 的后端 (Python/Pyspark)

numpy - 在另一个更大的数组中插入 3D 数组的值的最佳方法

python-3.x - 将数组复制到 NumPy 中另一个数组的一部分

multidimensional-array - 将 Array{T,N} 转换为 Array{Array{T,M},N-M} 的优雅方法

python - 是否有一个Python包可以解析带有节的可读数据文件

python - scipy.ndimage.laplace 中的边界模式

python - numpy 和 scipy 中的阶乘