Python numpy eig() 函数的完整性检查输出

Sanity Checking Output of Python numpy eig() function

我有一个关于 numpy.linalg.eig() 的问题。

这是对数据进行归一化/标准化后的协方差矩阵。

lr_cov = np.cov(lr_norm, rowvar = False, ddof = 0)
lr_cov

array([[ 0.95454545,  0.88156287,  0.8601369 ],
       [ 0.88156287,  0.95454545,  0.87367031],
       [ 0.8601369 ,  0.87367031,  0.95454545]])

我使用 eig() 函数如下 -- 这里没问题。

eig_val, eig_vec = np.linalg.eig(lr_cov)

eig_vec

array([[-0.57694452, -0.6184592 ,  0.53351967],
       [-0.57990975, -0.14982268, -0.80078577],
       [-0.57518668,  0.77140222,  0.27221115]])

eig_val

array([ 2.69815538,  0.09525935,  0.07022164])

但是当我继续检查 (Covariance Matrix)*(Eigen vector) = (Eigen Value)*(Eigen Vector) 时,在这种情况下,LHS 和 RHS 不匹配。

lr_cov*eig_vec

array([[-0.55071977, -0.54521067,  0.45889996],
       [-0.5112269 , -0.14301256, -0.69962276],
       [-0.49473928,  0.67395122,  0.25983791]])

eig_val*eig_vec

array([[-1.55668595, -0.05891402,  0.03746463],
       [-1.5646866 , -0.01427201, -0.05623249],
       [-1.55194302,  0.07348327,  0.01911511]])

我做错了什么?

两点:

  • * 是逐元素乘法。使用dot()方法进行矩阵乘法。
  • eig_val 是一维数组。使用 np.diag(eig_val).
  • 将其转换为二维方形对角线数组

示例:

In [70]: cov
Out[70]: 
array([[ 0.95454545,  0.88156287,  0.8601369 ],
       [ 0.88156287,  0.95454545,  0.87367031],
       [ 0.8601369 ,  0.87367031,  0.95454545]])

In [71]: eig_val, eig_vec = np.linalg.eig(cov)

In [72]: cov.dot(eig_vec)
Out[72]: 
array([[-1.55668595, -0.05891401,  0.03746463],
       [-1.56468659, -0.01427202, -0.05623249],
       [-1.55194302,  0.07348327,  0.01911511]])

In [73]: eig_vec.dot(np.diag(eig_val))
Out[73]: 
array([[-1.55668595, -0.05891401,  0.03746463],
       [-1.56468659, -0.01427202, -0.05623249],
       [-1.55194302,  0.07348327,  0.01911511]])

在最后一行,np.diag(eig_val)在右边,以便eig_vec的每一列乘以相应的特征值。

如果你利用了 numpy 的广播,你不必使用 np.diag(eig_val),你可以使用逐元素乘法(任意顺序,因为逐元素乘法是可交换的):

In [75]: eig_vec * eig_val  # element-wise multiplication with broadcasting

Out[75]: 
array([[-1.55668595, -0.05891401,  0.03746463],
       [-1.56468659, -0.01427202, -0.05623249],
       [-1.55194302,  0.07348327,  0.01911511]])

In [76]: eig_val * eig_vec
Out[76]: 
array([[-1.55668595, -0.05891401,  0.03746463],
       [-1.56468659, -0.01427202, -0.05623249],
       [-1.55194302,  0.07348327,  0.01911511]])