scipy.linalg.orth 使用 SVD 使矩阵正交。正交化后,向量按奇异值降序排列。然而,由于某些原因,我需要正交化向量在形状和顺序上尽可能与原始向量相似。
例如,对于矩阵,
>>> import scipy.linalg as sl
>>> import numpy as np
>>> A=np.array([[5,0,0],[0,2,0],[0,0,4]])
>>> A
array([[5, 0, 0],
[0, 2, 0],
[0, 0, 4]])
而不是按照奇异值5,4,2,
的降序得到正交化结果>>> sl.orth(A)
array([[1., 0., 0.],
[0., 0., 1.],
[0., 1., 0.]])
我想要的结果是
1 0 0
0 1 0
0 0 1
保持原始向量的顺序。有什么方法可以让我意识到这一点吗?感谢您的帮助!
您不能直接要求 SciPy 执行此操作。 SciPy 内部使用名为 gesdd 的 LAPACK 函数来执行此操作,该函数已经执行此排序,并且没有办法禁用它。
但是,您可以做的是比较每个正交向量与每个输入向量的余弦相似度,并根据与输入向量的相似度对正交向量进行排序。
示例:
import scipy.linalg
from scipy.spatial.distance import cdist
import numpy as np
def orth_preserving_order(A):
orthogonals_unordered = scipy.linalg.orth(A)
# Compute distance matrix
distance = cdist(A, orthogonals_unordered, metric='cosine')
# Convert cosine distance into cosine similarity
similarity_matrix = 1 - distance
# Consider vectors which are pointing in opposite direction to be "similar"
similarity_matrix = np.abs(similarity_matrix)
orthogonal_order_idx = []
for i in range(A.shape[0]):
vec_to_match = A[i]
# Pick element in orthogonals_unordered which is most similar to this row of A
best_vec_idx = similarity_matrix[i].argmax()
orthogonal_order_idx.append(best_vec_idx)
# Prevent this vector from being picked again
similarity_matrix[:, best_vec_idx] = -np.inf
# Sanity check - did we put any orthogonal vector in twice?
assert len(set(orthogonal_order_idx)) == len(orthogonal_order_idx), "duplicate orthogonal_order_idx"
# Did we use every vector?
assert len(orthogonal_order_idx) == A.shape[0], "missing vector in orthogonal_order_idx"
# Reorder orthogonals
orthogonal_reordered = orthogonals_unordered[orthogonal_order_idx]
return orthogonal_reordered
A=np.array([[5,0,0],[0,2,0],[0,0,4]])
print(orth_preserving_order(A))
输出:
[[1. 0. 0.]
[0. 1. 0.]
[0. 0. 1.]]