为什么协方差变化较小时特征向量的符号会翻转?

问题描述 投票:0回答:1

2 个协方差矩阵仅右上角和左下角的值不同。然而,主成分特征向量(右列)的符号已翻转。

import numpy as np


cov = np.array([[9369, 7060,   16469],
               [7060,  8127,   23034],
               [16469, 23034,  126402]])

eigenvalues, eigenvectors = np.linalg.eigh(cov)

print('Cov 1')
print(eigenvalues)
print(eigenvectors)

cov2 = np.array([[9369, 7060,   *18969*],
               [7060,   8127,   23034],
               [*18969*,  23034,  126402]])

eigenvalues, eigenvectors = np.linalg.eigh(cov2)

print('Cov 2')
print(eigenvalues)
print(eigenvectors)

结果:

Cov 1
[  1188.72951707   9507.3058357  133201.96464723]
[[-0.5549483   0.82002403  0.13997491]
 [ 0.8280924   0.52849364  0.18696912]
 [-0.07934332 -0.21967035  0.97234231]]
Cov 2
[  1390.92828009   8581.02234156 133926.04937835]
[[-0.57175381  0.80502124 -0.15823521]
 [ 0.817929    0.54427789 -0.18642352]
 [-0.06395096 -0.23601353 -0.96964318]]

我怎样才能防止这种情况发生,或者以某种方式“纠正”,以便符号相同 - 在两种情况下都是正数或负数?

python eigenvector
1个回答
0
投票

最后,我认为唯一可靠(但不是那么优雅)的解决方案是编写一个函数来手动进行检查(这里,我强制矩阵中的每个向量的第一个坐标为正。如果它为空,我检查第二个,依此类推。):

def adjust_eigenvectors(eigenvectors : np.ndarray):
    n,m = eigenvectors.shape
    for i in range(m):
        for j in range(n):
            if eigenvectors[j, i] > 0:
                break
            elif eigenvectors[j, i] < 0:
                eigenvectors[:, i] = -eigenvectors[:, i]
                break

    return eigenvectors

eigenvalues, eigenvectors = np.linalg.eigh(cov2)
print('Cov 2')
print(eigenvalues)
print(adjust_eigenvectors(eigenvectors))

请注意,此函数会就地执行此操作并返回值,因此从技术上讲,无需编写

return eigenvectors
,因为它已经被修改了。 我不太喜欢这个解决方案,因为它不是矢量化的(更不用说 numpy 风格的),但它修复了解决方案。

最新问题
© www.soinside.com 2019 - 2025. All rights reserved.