【问题标题】:Numpy eigenvector incorrect computationNumpy 特征向量计算不正确
【发布时间】:2014-02-12 22:20:26
【问题描述】:

我正在使用 numpy 来获取矩阵的特征值/特征向量。我的矩阵是对称且正的。

> mat

  matrix([[ 1.,  1.,  0.,  0.,  0.,  0.,  0.],
          [ 1.,  2.,  0.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  1.,  0.,  0.,  0.,  0.],
          [ 0.,  0.,  0.,  2.,  1.,  1.,  0.],
          [ 0.,  0.,  0.,  1.,  2.,  1.,  0.],
          [ 0.,  0.,  0.,  1.,  1.,  1.,  0.],
          [ 0.,  0.,  0.,  0.,  0.,  0.,  1.]])

我使用np.eigh,因为我的矩阵是对称的。

> import numpy.linalg as la
> la.eigh(mat)

  (array([ 0.27,  0.38,  1.  ,  1.  ,  1.  ,  2.62,  3.73]),
   matrix([[ 0.  , -0.85, -0.  ,  0.  ,  0.  ,  0.53,  0.  ],
          [ 0.  ,  0.53, -0.  ,  0.  ,  0.  ,  0.85,  0.  ],
          [ 0.  ,  0.  , -0.  ,  1.  ,  0.  ,  0.  ,  0.  ],
          [-0.33, -0.  , -0.71, -0.  , -0.  , -0.  , -0.63],
          [-0.33, -0.  ,  0.71, -0.  , -0.  , -0.  , -0.63],
          [ 0.89, -0.  , -0.  , -0.  , -0.  , -0.  , -0.46],
          [-0.  , -0.  , -0.  , -0.  ,  1.  , -0.  , -0.  ]]))

我的问题是其中许多值的符号错误。特别是,主特征向量(矩阵中最右边的列)在应该为正时都是负的。我已经对照 matlab 和 octave 对此进行了检查。这只是一个精度错误,还是我遗漏了什么?

如果是错误,有什么方法可以检查并纠正这种错误吗?

编辑:这个计算是Hubs and Authorities 的一部分,上面的矩阵是 A*A^T。这是the original paper (see p.9, p.10) 的结果,集线器分数收敛到 A*A^T 的主特征向量。最终,我们希望将这些中心分数相互比较,因此该标志实际上很重要。

在第 10 页,论文还说,“另外(作为推论),如果 M 只有非负项,则 M 的主特征向量只有非负项。”这就是我问这个问题的原因。

【问题讨论】:

  • 结果正确。特征向量的符号没有定义,是任意的。
  • 这些参考资料都没有与未定义特征向量的符号这一事实相矛盾。如果您的问题需要,您当然可以修复阶段约定,但通常不会这样做(因为问题各不相同)。

标签: python numpy eigenvalue


【解决方案1】:

特征向量的符号是任意的。据我所知,在这方面没有正确或错误的答案。

【讨论】:

  • 谢谢,迈克。我实际上关心特征向量的符号 - 我编辑了我原来的问题。
  • 看来作者草率了。他应该说过,“另外(作为推论),如果M只有非负条目,那么存在一个 M的主特征向量,它只有非负条目。” (或更清晰的措辞),这就是 Perron-Frobenius 定理实际所说的。
  • 要获得您需要的标志,请随意翻转整个矢量上的标志。
  • 是的,我也在研究 Perron-Frobenius 定理。很明显,论文中描述的迭代方法只给出了非负结果,但一般情况下并非如此。我现在的问题是,我能确定主特征向量的所有元素都具有相同的符号吗?不过,这比 numpy 更数学。
  • 类似eigvals, eigvecs = la.eigh(mat)principal = eigvecs[:, eigvals.argmax()]if (principal >= 0).all() or (pricipal <= 0).all(): print 'all the same'? (未运行/测试/等。此外,可能会遇到 -0.000000000218 应计为 0 的数字问题)。首先发短信mat 可能更容易。)
【解决方案2】:

如果您利用MM == QQ*DD*QQ.T,您可以轻松检查对称矩阵MM 的特征分解是否正确,其中DD=diag([lam_1, lam2_,...]) 是对角线上的特征值矩阵,QQ 是特征向量矩阵:

lam,QQ = la.eigh(MM)

# Check result:
DD = np.diag(lam)
MM2 = np.dot(np.dot(QQ, DD), QQ.T)
print(MM-MM2)  # should be zero

在您的情况下正确为 14 位。

请注意,特征向量可以乘以任何常数,因为特征值的定义方程 MM*x == lambda*x MM*(c*x) == lambda *(c*x)c 是任何非零常数。 c 取决于数字 - Numpy 只是将向量标准化为 1。

【讨论】:

    猜你喜欢
    • 2013-09-17
    • 1970-01-01
    • 1970-01-01
    • 2011-12-11
    • 2015-06-30
    • 1970-01-01
    • 1970-01-01
    • 2015-03-03
    • 1970-01-01
    相关资源
    最近更新 更多