SVD理论以及Python实现

系统 1651 0

SVD

将一个矩阵分解为U,V(U,V均为列正交矩阵,即列向量直接内积为0),中间的矩阵为对角阵,元素为奇异值。

A [ m ∗ n ] = U [ m ∗ r ] ∗ ∑ [ r ∗ r ] ∗ ( V [ n ∗ r ] ) T A_{[m*n]} = U_{[m*r]} * \sum_{[r*r]} *(V_{[n*r]})^T A [ m n ] = U [ m r ] [ r r ] ( V [ n r ] ) T

SVD计算方式

A = U ∗ ∑ ∗ V T A T = V ∗ ∑ ∗ U T A A T = U ∗ ∑ ∗ V T ∗ V ∗ ∑ ∗ U T A = U * \sum * V^T \\ A^T = V * \sum * U ^T \\ AA^T = U * \sum * V^T * V * \sum * U^T A = U V T A T = V U T A A T = U V T V U T

  • 由于其为列正交向量,所以矩阵在非对角位置都为0, 因此当V的列向量是单位向量时,对角位为1,则为单位阵。

A A T = U ∑ 2 U T A A T U = U ∑ 2 AA^T = U {\sum}^2U^T \\ AA^T U = U {\sum}^2 A A T = U 2 U T A A T U = U 2
因此,U为 A A T AA^T A A T 特征向量构成的矩阵,然后 ∑ 2 {\sum}^2 2 的对角元为特征值。

同理,可知, A T A A^TA A T A 对应于V的计算。

Python实现

  • 导入包
            
              
                import
              
               numpy 
              
                as
              
               np

            
          
  • 创建数据
            
              A 
              
                =
              
               np
              
                .
              
              linspace
              
                (
              
              
                0
              
              
                ,
              
              
                14
              
              
                ,
              
              
                15
              
              
                )
              
              
                .
              
              reshape
              
                (
              
              
                (
              
              
                3
              
              
                ,
              
              
                -
              
              
                1
              
              
                )
              
              
                )
              
              
A

            
          
            
              array
              
                (
              
              
                [
              
              
                [
              
              
                0
              
              
                .
              
              
                ,
              
              
                1
              
              
                .
              
              
                ,
              
              
                2
              
              
                .
              
              
                ,
              
              
                3
              
              
                .
              
              
                ,
              
              
                4
              
              
                .
              
              
                ]
              
              
                ,
              
              
                [
              
              
                5
              
              
                .
              
              
                ,
              
              
                6
              
              
                .
              
              
                ,
              
              
                7
              
              
                .
              
              
                ,
              
              
                8
              
              
                .
              
              
                ,
              
              
                9
              
              
                .
              
              
                ]
              
              
                ,
              
              
                [
              
              
                10
              
              
                .
              
              
                ,
              
              
                11
              
              
                .
              
              
                ,
              
              
                12
              
              
                .
              
              
                ,
              
              
                13
              
              
                .
              
              
                ,
              
              
                14
              
              
                .
              
              
                ]
              
              
                ]
              
              
                )
              
            
          
  • 实现
            
              
                def
              
              
                SVD
              
              
                (
              
              A
              
                ,
              
               n
              
                )
              
              
                :
              
              
    M 
              
                =
              
               np
              
                .
              
              dot
              
                (
              
              A
              
                ,
              
               A
              
                .
              
              T
              
                )
              
              
    eigval
              
                ,
              
               eigvec 
              
                =
              
               np
              
                .
              
              linalg
              
                .
              
              eig
              
                (
              
              M
              
                )
              
              
    indexes 
              
                =
              
               np
              
                .
              
              argsort
              
                (
              
              
                -
              
              eigval
              
                )
              
              
                [
              
              
                :
              
              n
              
                ]
              
              
    U 
              
                =
              
               eigvec
              
                [
              
              
                :
              
              
                ,
              
               indexes
              
                ]
              
              
    sigma_sq 
              
                =
              
               eigval
              
                [
              
              indexes
              
                ]
              
              
    M 
              
                =
              
               np
              
                .
              
              dot
              
                (
              
              A
              
                .
              
              T
              
                ,
              
               A
              
                )
              
              
    eigval
              
                ,
              
               eigvec 
              
                =
              
               np
              
                .
              
              linalg
              
                .
              
              eig
              
                (
              
              M
              
                )
              
              
    indexes 
              
                =
              
               np
              
                .
              
              argsort
              
                (
              
              
                -
              
              eigval
              
                )
              
              
                [
              
              
                :
              
              n
              
                ]
              
              
    V 
              
                =
              
               eigvec
              
                [
              
              
                :
              
              
                ,
              
               indexes
              
                ]
              
              
    sigma 
              
                =
              
               np
              
                .
              
              diag
              
                (
              
              np
              
                .
              
              sqrt
              
                (
              
              sigma_sq
              
                )
              
              
                )
              
              
                #     print(sigma)
              
              
                return
              
               np
              
                .
              
              dot
              
                (
              
              np
              
                .
              
              dot
              
                (
              
              U
              
                ,
              
               sigma
              
                )
              
              
                ,
              
               V
              
                .
              
              T
              
                )
              
            
          
  • 调用
            
              A_ 
              
                =
              
               SVD
              
                (
              
              A
              
                ,
              
              
                2
              
              
                )
              
              
A_

            
          
            
              array
              
                (
              
              
                [
              
              
                [
              
              
                2.01625019e-16
              
              
                ,
              
              
                1.00000000e+00
              
              
                ,
              
              
                2.00000000e+00
              
              
                ,
              
              
                3.00000000e+00
              
              
                ,
              
              
                4.00000000e+00
              
              
                ]
              
              
                ,
              
              
                [
              
              
                5.00000000e+00
              
              
                ,
              
              
                6.00000000e+00
              
              
                ,
              
              
                7.00000000e+00
              
              
                ,
              
              
                8.00000000e+00
              
              
                ,
              
              
                9.00000000e+00
              
              
                ]
              
              
                ,
              
              
                [
              
              
                1.00000000e+01
              
              
                ,
              
              
                1.10000000e+01
              
              
                ,
              
              
                1.20000000e+01
              
              
                ,
              
              
                1.30000000e+01
              
              
                ,
              
              
                1.40000000e+01
              
              
                ]
              
              
                ]
              
              
                )
              
            
          

非常近了,然后量化判断下,用二范数来测量下:

            
              np
              
                .
              
              linalg
              
                .
              
              norm
              
                (
              
              A_ 
              
                -
              
               A
              
                )
              
            
          
  • 总共的误差: 1.8697717541841314e-14
  • 非常的小了。

更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论