填坑之作-python实现SVD

本想使用python实现的一下SVD的各个步骤,然后就用一些库来实现特征向量和特征值的求解分解,然后最后得到SVD的结果,但是在上手的过程中,发生了一些很诡异的事情,在这里记录一下

首先是以下的实现

def SVD(A):
    AtA = np.dot(A.T, A)
    AAt = np.dot(A, A.T)

    AtAe, AtAv = np.linalg.eig(AtA)
    AAte, AAtv = np.linalg.eig(AAt)
    print(AtAe)
    print(AtAv)
    dia=np.eye(A.shape[0],A.shape[1])*np.sqrt(AtAe)
    return AAtv,dia,AtAv.T

SVD的思路很简单,给一个需要进行SVD的矩阵A(以下以https://zhuanlan.zhihu.com/p/29846048中的矩阵A为例)

这是我们的A:

[[0 1]
 [1 1]
 [1 0]]

1、计算A^TA 、以及其特征值(AtAe)和特征向量(AtAv),结果如下:

AtA:[[2 1]
 [1 2]]

AtAe:[3. 1.]

AtAv:[[ 0.70710678 -0.70710678]
 [ 0.70710678  0.70710678]]

可以看到和源例子中手解的结果相同

 

2、计算AA^T、以及其特征值(AAte)和特征向量(AAtv),结果如下:

AtA:[[1 1 0]
 [1 2 1]
 [0 1 1]]
AAte:[ 3.00000000e+00  1.00000000e+00 -3.36770206e-17]
AAtv:[[-4.08248290e-01  7.07106781e-01  5.77350269e-01]
 [-8.16496581e-01  2.61214948e-16 -5.77350269e-01]
 [-4.08248290e-01 -7.07106781e-01  5.77350269e-01]]

可以看到和源例子中手解的结果当特征值为3的时候,特征向量相差一个负号,但是不影响特征值特征向量的性质A\beta =\lambda \beta

 

3、最后使用,程序中为dia,

[[1.73205081 0.        ]
 [0.         1.        ]
 [0.         0.        ]]

4、返回AAtv、dia、AtAv.T作为U,S,V完成SVD分解

AAtv:[[-4.08248290e-01  7.07106781e-01  5.77350269e-01]
 [-8.16496581e-01  2.61214948e-16 -5.77350269e-01]
 [-4.08248290e-01 -7.07106781e-01  5.77350269e-01]]
dia:[[1.73205081 0.        ]
 [0.         1.        ]
 [0.         0.        ]]
AtAv.T:[[ 0.70710678  0.70710678]
 [-0.70710678  0.70710678]]

但是当演算A=U*S*V的时候,得到的结果却是

U*S*V:[[-1.00000000e+00  3.32444579e-16]
 [-1.00000000e+00 -1.00000000e+00]
 [-1.21168839e-16 -1.00000000e+00]]

并不等于源A

因此就想要直接调用np.linalg.svd看一下它给出的结果是什么,结果如下

U:[[-4.08248290e-01  7.07106781e-01  5.77350269e-01]
 [-8.16496581e-01  2.64811510e-17 -5.77350269e-01]
 [-4.08248290e-01 -7.07106781e-01  5.77350269e-01]]
S:[1.73205081 1.        ]
V:[[-0.70710678 -0.70710678]
 [-0.70710678  0.70710678]]

 发现它所求出的U、S和我求出的相同,但是V却和我的大有不同,查遍所有资料,后来在https://zhuanlan.zhihu.com/p/43578482中找到解释,由于V是求解出来的特征向量需要在进行transpose,然而计算机给出的特征向量可能会有一个符号的差距,而那个符号的差距正好可能会被tranpose,就导致了最终的结果不正确

发布了164 篇原创文章 · 获赞 36 · 访问量 5万+

猜你喜欢

转载自blog.csdn.net/py184473894/article/details/99689266