1、特征值分解

主要还是调包:

  1. from numpy.linalg import eig

特征值分解:  A = P*B*PT  当然也可以写成 A = QT*B*Q  其中B为对角元为A的特征值的对角矩阵,P=QT

首先A得对称正定,然后才能在实数域上分解,

  1. >>> A = np.random.randint(-10,10,(4,4))
  2. >>> A
  3. array([[ 6, 9, -10, -1],
  4. [ 5, 9, 5, -5],
  5. [ -8, 7, -4, 4],
  6. [ -1, -9, 0, 6]])
  7.  
  8. >>> C = np.dot(A.T, A)
  9. >>> C
  10. array([[126, 52, -3, -69],
  11. [ 52, 292, -73, -80],
  12. [ -3, -73, 141, -31],
  13. [-69, -80, -31, 78]])
  14.  
  15. >>> vals, vecs = eig(C)
  16. >>> vals
  17. array([357.33597086, 174.10172008, 8.84429957, 96.71800949])
  18. >>> vecs
  19. array([[-0.28738314, -0.51589436, -0.38221983, -0.71075449],
  20. [-0.87487263, 0.12873861, -0.24968051, 0.39456798],
  21. [ 0.2572149 , -0.69304313, -0.33950158, 0.58161018],
  22. [ 0.29300052, 0.48679627, -0.82237845, -0.02955945]])

故使用时应先将特征值转换为矩阵:

  1. >>> Lambda = np.diag(vals)
  2. >>> Lambda
  3. array([[357.33597086, 0. , 0. , 0. ],
  4. [ 0. , 174.10172008, 0. , 0. ],
  5. [ 0. , 0. , 8.84429957, 0. ],
  6. [ 0. , 0. , 0. , 96.71800949]])
  7.  
  8. >>> np.dot(np.dot(vecs, Lambda), vecs.T) # 与C=A.T*A相等
  9. array([[126., 52., -3., -69.],
  10. [ 52., 292., -73., -80.],
  11. [ -3., -73., 141., -31.],
  12. [-69., -80., -31., 78.]])
  13.  
  14. >>> np.dot(np.dot(vecs.T, Lambda), vecs)
  15. array([[171.65817919, 45.58778569, 53.20435074, 13.37512137],
  16. [ 45.58778569, 125.15670964, 28.22684299, 134.91290105],
  17. [ 53.20435074, 28.22684299, 129.48789571, 80.5284382 ],
  18. [ 13.37512137, 134.91290105, 80.5284382 , 210.69721545]])

故验证了使用np中的eig分解为A=P*B*PT 而不是A=QT*B*Q,其中P=vecs,

即 C = vecs * np.diag(vals) * vecs.T # 这里简写*为矩阵乘法

然后再来看使用np中的eig分解出来的vec中行向量是特征向量还是列向量是特征向量,只需验证:A*vecs[0] = vals[0]*vecs[0]

  1. >>> np.dot(C, vecs[0])
  2. array([-12.84806258, -80.82266859, 6.66283128, 17.51094927])
  3. >>> vals[0]*vecs[0]
  4. array([-102.69233303, -184.34761071, -136.58089252, -253.97814676])
  5.  
  6. >>> np.dot(C, vecs[:,0])
  7. array([-102.69233303, -312.62346098, 91.91213634, 104.69962583])
  8. >>> vals[0]*vecs[:, 0]
  9. array([-102.69233303, -312.62346098, 91.91213634, 104.69962583])

后者两个是相等的,故使用np中的eig分解出的vecs的列向量是特征向量。

然后我们可以验证P是单位正交矩阵:

  1. >>> np.dot(vecs.T, vecs)
  2. array([[ 1.00000000e+00, -7.13175042e-17, -2.45525952e-18,
  3. 2.75965773e-16],
  4. [-7.13175042e-17, 1.00000000e+00, 2.49530948e-17,
  5. -5.58839097e-16],
  6. [-2.45525952e-18, 2.49530948e-17, 1.00000000e+00,
  7. -7.85564967e-17],
  8. [ 2.75965773e-16, -5.58839097e-16, -7.85564967e-17,
  9. 1.00000000e+00]])
  10.  
  11. >>> np.dot(vecs, vecs.T)
  12. array([[ 1.00000000e+00, 2.97888865e-16, -2.68317972e-16,
  13. 1.69020590e-16],
  14. [ 2.97888865e-16, 1.00000000e+00, -4.40952204e-18,
  15. -6.24188690e-17],
  16. [-2.68317972e-16, -4.40952204e-18, 1.00000000e+00,
  17. -1.13726775e-17],
  18. [ 1.69020590e-16, -6.24188690e-17, -1.13726775e-17,
  19. 1.00000000e+00]])
  20.  
  21. # 可以看到除对角元外其他都是非常小的数

PT*P = P*PT = E , PT=P-1。事实上,在求解P的过程中就使用了施密特正交化过程。

另一方面,我们从数学角度来看:

首先补充一些数学知识:可以看我另一篇文章:矩阵知识

A = P*B*P-1  ,其中B为对角元素为A的特征值的对角阵,P的列向量为特征值对应的特征向量(因为B每行乘以P每列)

2、奇异值分解

还是调包:

  1. from numpy.linalg import svd

设任意矩阵A是m*n矩阵

奇异值分解:A = U*Σ*VT , 其中U为满足UTU=E的m阶(m*m)酉矩阵,Σ为对角线上为奇异值σi 其他元素为0的广义m*n对角阵,V为满足VTV=E的n阶(n*n)酉矩阵

  1. a = np.random.randint(-10,10,(4, 3)).astype(float)
  2.  
  3. '''
  4. array([[ -9., 3., -7.],
  5. [ 4., -8., -1.],
  6. [ -1., 6., -9.],
  7. [ -4., -10., 2.]])
  8. '''
  9.  
  10. In [53]: u, s, vh = np.linalg.svd(a) # 这里vh为V的转置
  11.  
  12. In [55]: u.shape, s.shape, vh.shape
  13. Out[55]: ((4, 4), (3,), (3, 3))
  14.  
  15. '''
  16. In [63]: u
  17. Out[63]:
  18. array([[-0.53815289, 0.67354057, -0.13816841, -0.48748749],
  19. [ 0.40133556, 0.1687729 , 0.78900752, -0.43348888],
  20. [-0.59291924, 0.04174708, 0.59180987, 0.54448603],
  21. [ 0.44471115, 0.71841213, -0.09020922, 0.52723647]])
  22.  
  23. In [64]: s
  24. Out[64]: array([16.86106528, 11.07993065, 7.13719934])
  25.  
  26. In [65]: vh
  27. Out[65]:
  28. array([[ 0.31212695, -0.760911 , 0.56885078],
  29. [-0.74929793, -0.56527432, -0.3449892 ],
  30. [ 0.58406282, -0.31855829, -0.74658639]])
  31. '''
  32.  
  33. In [56]: np.allclose(a, np.dot(u[:, :3] * s, vh))
  34. Out[56]: True
  35.  
  36. # 将s转化为奇异值矩阵
  37. In [60]: smat[:3, :3] = np.diag(s)
  38.  
  39. In [61]: smat
  40. Out[61]:
  41. array([[16.86106528, 0. , 0. ],
  42. [ 0. , 11.07993065, 0. ],
  43. [ 0. , 0. , 7.13719934],
  44. [ 0. , 0. , 0. ]])
  45.  
  46. # 验证分解的正确性
  47. In [62]: np.allclose(a, np.dot(u, np.dot(smat, vh)))
  48. Out[62]: True

讲一下numpy的矩阵特征值分解与奇异值分解的更多相关文章

  1. 数学基础系列(六)----特征值分解和奇异值分解(SVD)

    一.介绍 特征值和奇异值在大部分人的印象中,往往是停留在纯粹的数学计算中.而且线性代数或者矩阵论里面,也很少讲任何跟特征值与奇异值有关的应用背景. 奇异值分解是一个有着很明显的物理意义的一种方法,它可 ...

  2. 特征值分解,奇异值分解(SVD)

    特征值分解和奇异值分解在机器学习领域都是属于满地可见的方法.两者有着很紧密的关系,我在接下来会谈到,特征值分解和奇异值分解的目的都是一样,就是提取出一个矩阵最重要的特征. 1. 特征值: 如果说一个向 ...

  3. matlab特征值分解和奇异值分解

    特征值分解 函数 eig 格式 d = eig(A)         %求矩阵A的特征值d,以向量形式存放d. d = eig(A,B)       %A.B为方阵,求广义特征值d,以向量形式存放d. ...

  4. 特征值分解与奇异值分解(SVD)

    1.使用QR分解获取特征值和特征向量 将矩阵A进行QR分解,得到正规正交矩阵Q与上三角形矩阵R.由上可知Ak为相似矩阵,当k增加时,Ak收敛到上三角矩阵,特征值为对角项. 2.奇异值分解(SVD) 其 ...

  5. 【ML】从特征分解,奇异值分解到主成分分析

    1.理解特征值,特征向量 一个对角阵\(A\),用它做变换时,自然坐标系的坐标轴不会发生旋转变化,而只会发生伸缩,且伸缩的比例就是\(A\)中对角线对应的数值大小. 对于普通矩阵\(A\)来说,是不是 ...

  6. 基于numpy实现矩阵计算器

    要求 制作一个Python的矩阵计算器: ① 程序提供任意两矩阵的加.乘法运算:方阵的行列式计算.逆矩阵计算.特征分解:任意矩阵的转置等计算功能,可自行添加功能 ② 从控制台通过键盘获取数据并完成以上 ...

  7. 【SVD、特征值分解、PCA关系】

    一.SVD    1.含义: 把矩阵分解为缩放矩阵+旋转矩阵+特征向量矩阵. A矩阵的作用是将一个向量从V这组正交基向量的空间旋转到U这组正交基向量的空间,并对每个方向进行了一定的缩放,缩放因子就是各 ...

  8. numpy创建矩阵常用方法

    numpy创建矩阵常用方法 arange+reshape in: n = np.arange(0, 30, 2)# start at 0 count up by 2, stop before 30 n ...

  9. Python numpy中矩阵的用法总结

    关于Python Numpy库基础知识请参考博文:https://www.cnblogs.com/wj-1314/p/9722794.html Python矩阵的基本用法 mat()函数将目标数据的类 ...

随机推荐

  1. 理解Global interpreter lock

      Global interpreter lock (GIL) is a mechanism used in computer language interpreters to synchronize ...

  2. django模型:字段和选项

    https://blog.csdn.net/iloveyin/article/details/44852645一.常用字段1.字段类型使用时需要引入django.db.models包,字段类型如下Au ...

  3. Java基础—注解(转载)

    概念 注解(Annotation),也叫元数据.一种代码级别的说明.它是JDK1.5及以后版本引入的一个特性,与类.接口.枚举是在同一个层次.它可以声明在包.类.字段.方法.局部变量.方法参数等的前面 ...

  4. Redis vs Mongo vs mysql

    Redis 和 Mongo 都属于 No-SQL类型的数据库,他们的区别,联系是什么呢?看了一些文章,特总结如下. Redis 最大的特点是,快!为什么快,因为他将大量的东西存储在了memory中.但 ...

  5. mysql应用实例

    目录: 表结构 sql练习 1.表结构 SET NAMES utf8; SET FOREIGN_KEY_CHECKS = 0; -- ---------------------------- -- T ...

  6. gui设计

    芯艺,你好! ... ... ... 芯艺,再见! http://www.chipart.cn/ 附件 http://files.cnblogs.com/files/dong1/%E8%89%BA%E ...

  7. python学习笔记(二)文件操作和集合

    集合: 集合也是一种数据类型,一个类似列表东西,它的特点是无序的,不重复的,也就是说集合中是没有重复的数据 集合的作用: 1.它可以把一个列表中重复的数据去掉,而不需要你再写判断 2.可以做关系测试, ...

  8. karma安装

    Last login: Sat Jun :: on ttys000 ➜ ~ cd /Users/wangyizhe/Projects/work/smartcmp/services/new-yacmp/ ...

  9. Spark2.0机器学习系列之9: 聚类(k-means,Bisecting k-means,Streaming k-means)

    在Spark2.0版本中(不是基于RDD API的MLlib),共有四种聚类方法:      (1)K-means      (2)Latent Dirichlet allocation (LDA)  ...

  10. PAT 1116 Come on! Let's C [简单]

    1116 Come on! Let's C (20 分) "Let's C" is a popular and fun programming contest hosted by ...