python - numpy 中检查向量是否对齐或方向相反的最快方法(截断的 SVD 后处理)

标签 python numpy vector svd eigenvalue

我有一堆向量存储在矩阵 U 的列中。 我还有一个包含列向量的矩阵 V 。 V 中的每个向量可以是

  • 与 U 中的对应部分几乎相同,具有数值近似值
  • 或具有相反的符号,具有数值近似值。

目标是找到一个数组,如果向量具有相同方向,则包含 1;如果向量方向相反,则包含 -1。

另外两件事:

  • 我只对最初的迹象感兴趣,而不是全部(在下面的示例中是 10000 中的 100)。
  • V 以其转置形式 (Vt) 给出

到目前为止我已经找到了三种方法来解决这个问题:

from timeit import timeit
import numpy as np

# create fake SVD output
n_components = 100
n_samples = 10000
U = np.random.random((n_samples, n_samples - 1))
true_signs = np.sign(np.random.random(n_samples - 1) - 0.5)
Vt = np.multiply(U, true_signs[None, :]).T
# simulate some numerical imprecision
Vt += np.random.random((n_samples - 1, n_samples)) * 0.001

# 3 competing methods
def compute_signs_dot():
    VtU = np.dot(Vt[:n_components, :], U[:, :n_components])
    signs = np.sign(np.diag(VtU))
    np.testing.assert_equal(signs, true_signs[:n_components])

def compute_signs_mul():
    diag_VtU = np.multiply(Vt[:n_components, :].T,
                          U[:, :n_components]).sum(axis=0)
    signs = np.sign(diag_VtU)
    np.testing.assert_equal(signs, true_signs[:n_components])

def compute_signs_sign():
    signs = np.multiply(np.sign(Vt[:n_components, :].T),
                        np.sign(U[:, :n_components])).sum(axis=0)
    signs = np.sign(signs)
    np.testing.assert_equal(signs, true_signs[:n_components])

# compare execution times
print("compute_signs_dot: %.3fs" % timeit(compute_signs_dot, number=100))
print("compute_signs_mul: %.3fs" % timeit(compute_signs_mul, number=100))
print("compute_signs_sign: %.3fs" % timeit(compute_signs_sign, number=100))

产量

compute_signs_dot: 2.001s
compute_signs_mul: 0.786s
compute_signs_sign: 1.693s

因此,迄今为止最快的方法似乎是通过将项与项相乘并求和来计算每个列索引处的向量对之间的标量积 (compute_signs_mul)。

任何其他更快或类似速度的方法将不胜感激。

注意:正如一些读者可能已经注意到的,这是对截断 SVD 输出的后处理,以便通过查找符号将奇异值转换为特征值。

最佳答案

我们可以使用np.einsum -

diag_VtU = np.einsum('ji,ij->j',Vt[:n_components, :], U[:, :n_components])

或者,使用 np.matmul/@-operator 获取 diag_VtU -

(Vt[:n_components, :][:,None,:] @ (U[:, :n_components].T)[:,:,None])[:,0,0]

关于python - numpy 中检查向量是否对齐或方向相反的最快方法(截断的 SVD 后处理),我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/61973915/

相关文章:

python - 跨平台 Python 扫描器接口(interface)

python - 为什么 Serverless 在尝试打包或部署时会产生 Invalid Cross-device link 错误?

python - 具有可变输入形状的 Keras

Python--读取 dat 文件行,重写 Excel 中的列。 csv/numpy/openpyxl

python - 使用 python 保存和绘制多个数据集

c++ - 3D - 来自方向 vector (向前、向上、向右)的旋转矩阵

vector - VHDL表达式不是常数

python - web.py db.insert函数抛出错误: <type 'exceptions.TypeError' > : 'long' object is unsubscriptable

python - 如何显示 scipy.optimize 函数的进度?

c++ - 这种方法会涉及内存重新分配从而影响其效率吗?