gpt4 book ai didi

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

转载 作者:行者123 更新时间:2023-12-04 09:53:32 24 4
gpt4 key购买 nike

我有一堆向量存储在矩阵 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/

    24 4 0
    Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
    广告合作:1813099741@qq.com 6ren.com