特征值分解和奇异值分解以及使用numpy实现

【时间】2018.12.08

【题目】特征值分解和奇异值分解以及使用numpy实现

目录

一、特征值分解(EIG)

1.1 定义

1.2 在python中实现特征值分解

二、奇异值分解(singular Value Decomposition)

2.1、定义

2.2 在python中实现奇异值分解


一、特征值分解(EIG)

注意:只有方阵才能进行特征值分解

1.1 定义

 如果说一个向量v是方阵A的特征向量,将一定可以表示成下面的形式:

    这时候λ就被称为特征向量v对应的特征值,一个矩阵的一组特征向量是一组正交向量。特征值分解是将一个矩阵分解成下面的形式:

    其中Q是这个矩阵A的特征向量组成的矩阵,Σ是一个对角阵,每一个对角线上的元素就是一个特征值。首先,要明确的是,一个矩阵其实就是一个线性变换,因为一个矩阵乘以一个向量后得到的向量,其实就相当于将这个向量进行了线性变换。

1.2 在python中实现特征值分解

numpy中的linalg已经实现了ELG,可以直接调用,具体为:

e_vals,e_vecs = np.linalg.eig(a)

输入参数:a为需要分解的方阵

返回:

  • e_vals:由特征值构成的向量
  • e_vecs:由特征向量构成的矩阵

以下是测试代码:

注意矩阵求逆可以使用np.linalg.inv(a)

【代码】

import numpy as np

a = np.random.randn(4, 4)

e_vals,e_vecs = np.linalg.eig(a)

print('分解得到的形状:\n',e_vals.shape,e_vecs.shape )

print('特征值:\n',e_vals)

print('特征向量矩阵:\n',e_vecs)

smat=np.zeros((4,4))

smat= np.diag(e_vals)

#验证特征值分解

result=np.allclose( a, np.dot(e_vecs, np.dot(smat, np.linalg.inv(e_vecs))))#对比两个矩阵的各个元素,若一致则返回True

print('验证特征值分解:\n',result)

【运行结果】

二、奇异值分解(singular Value Decomposition)

2.1、定义

       奇异值分解(singular Value Decomposition),简称SVD,线性代数中矩阵分解的方法。假如有一个矩阵A,对它进行奇异值分解,可以得到三个矩阵:

 

(情况一)这三个矩阵的大小:

 

矩阵sigma(即上图U和V中间的矩阵)除了对角元素不为0,其他元素都为0,并且对角元素是从大到小排列的,前面的元素比较大,后面的很多元素接近0。这些对角元素就是奇异值

(情况二)sigma中有n个奇异值,但是由于排在后面的很多接近0,所以我们可以仅保留比较大的r个奇异值,此时奇异值分解为:

 

实际应用中,我们仅需保留着三个比较小的矩阵,就能表示A,不仅节省存储量,在计算的时候更是减少了计算量。

 

2.2 在python中实现奇异值分解

numpy中的linalg已经实现了SVD,可以直接调用,具体为:

U,S,Vh= numpy.linalg.svd(a, full_matrices=True, compute_uv=True)[source]

输入参数:

  •  a 为要分解的矩阵 ,维数>=2,即(...,M,N)
  •  full_matrices是bool值,默认为True,此时分解出的U和Vh矩阵的形状分别为 (..., M, M)和(..., N, N),即2.1中的情况一,否则为 (..., M, K)和(..., K, N),这里K = min(M, N),即2.1中的情况二
  • compute_uv 也是bool值, 表示除S之外s是否计算U和Vh的值,默认为True,即结果返回3个矩阵

返回值:2.1中的3个矩阵

注意: 无论何种情况,返回的奇异矩阵都只是由奇异值组成的一个向量(而且是省略零值的),如果想要获得对应的奇异矩阵,可以使用np.diag(s)进行构建。详细用法请查阅:https://docs.scipy.org/doc/numpy/reference/generated/numpy.linalg.svd.html#numpy.linalg.svd

以下是测试代码:

(1)情况一(默认full_matrices=True)

【代码】

import numpy as np

a = np.random.randn(9, 6)

u, s, vh = np.linalg.svd(a)

print('分解得到矩阵的形状:\n',u.shape,s.shape,vh.shape)

print('奇异值:\n',s)

smat=np.zeros((9,6))

smat[:6,:6]= np.diag(s)

print('奇异矩阵:\n',smat)

#验证奇异值分解

result=np.allclose(a, np.dot(u, np.dot(smat, vh)))#对比两个矩阵的各个元素,若一致则返回True

print(result)

【运行结果】

(2)情况二( full_matrices=False)

【代码】

import numpy as np

a = np.random.randn(9, 6)

u, s, vh = np.linalg.svd(a, full_matrices=False)

print('分解得到矩阵的形状:\n',u.shape,s.shape,vh.shape)

smat = np.zeros((6, 6))

print('奇异值:\n',s)

smat= np.diag(s)

print('奇异矩阵:\n',smat)

#验证奇异值分解

result=np.allclose(a, np.dot(u, np.dot(smat, vh)))#对比两个矩阵的各个元素,若一致则返回True

print(result)

【运行结果】

参考文献

http://www.cnblogs.com/LeftNotEasy/archive/2011/01/19/svd-and-applications.html

  • 17
    点赞
  • 61
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值