前面咱们讲了 QR 分解有一些优良的特性,可是 QR 分解仅仅是对矩阵的行进行操做(左乘一个酉矩阵),能够获得列空间。这一小节的 SVD 分解则是将行与列同等看待,既左乘酉矩阵,又右乘酉矩阵,能够得出更有意思的信息。奇异值分解( SVD, Singular Value Decomposition ) 在计算矩阵的伪逆( pseudoinverse ),最小二乘法最优解,矩阵近似,肯定矩阵的列向量空间,秩以及线性系统的解集空间都有应用。html
对于一个任意的 m×n 的矩阵 A,SVD 将一个矩阵分解为三个特殊矩阵的乘积, 国外还作了一个视频——SVD 之歌:python
其中, U 和 是酉矩阵,
是对角线矩阵。注意酉矩阵只是坐标的转换,数据自己分布的形状并无改变,而对角矩阵,则是对数据进行了拉伸或者压缩。因为 m
>=
n,又能够写成下面这种 thin SVD 形式:python2.7
考虑 A 是 2×2 的简单状况。咱们知道,一个几何形状左乘一个矩阵 A 实际上就是将该形状进行旋转、对称、拉伸变换等错切变换, A 就是所谓的 shear 矩阵。好比能够将一个圆经过左乘 A 获得一个旋转后的椭圆。工具
举个例子,假设 A 对平面上的一个圆进行变换:spa
若是只看矩阵 A, 咱们几乎没法直观看到圆是如何变换的。变换前的圆是:3d
C, M, Y, K 分别表示第1、2、3、四象限。左乘 A 矩阵后获得:code
咱们的问题是,旋转了多少度?伸缩的方向是多少?最大伸缩比例是多少?视频
利用这个在线工具对 A 进行 SVD 分解:htm
明显,咱们看到 A 变换其实是先对圆顺时针旋转 45°(能够看作是坐标轴逆时针宣战了 45°,主成分方向),再关于 x 轴对称(第一行乘以 -1), 即左乘 V^T:blog
而后在 x 方向拉伸 3 倍(左乘S):
最后再顺时针旋转 45°,再关于 x 轴对称(第一行乘以 -1, 两次对称操做抵消了), 即左乘 U:
上述绘图过程的 python 代码以下:
1 # -*- coding=utf-8 2 #!/usr/bin/python2.7 3 4 from pylab import * 5 6 7 def plotCircle(before, M=matrix([[1, 0], [0, 1]])): 8 '''before: 变换前的矩阵 9 M: 变换矩阵,默认为单位矩阵 10 返回变换以后的矩阵 11 ''' 12 eclMat = M * before # M 变换 13 eclX = array(eclMat[0]).reshape(-1) 14 eclY = array(eclMat[1]).reshape(-1) 15 axis('equal') 16 axis([-3, 3, -3, 3]) 17 grid(True) 18 plot(eclX[:25], eclY[:25], 'c', linewidth=3) 19 plot(eclX[25:50], eclY[25:50], 'm', linewidth=3) 20 plot(eclX[50:75], eclY[50:75], 'y', linewidth=3) 21 plot(eclX[75:100], eclY[75:100], 'k', linewidth=3) 22 show() 23 return eclMat 24 25 26 ang = linspace(0, 2*pi, 100) 27 28 x = cos(ang) 29 y = sin(ang) 30 cirMat = matrix([x, y]) # 2 × 100 的圆圈矩阵 31 32 # 画最开始的图形——圆 33 plotCircle(cirMat) 34 35 # 画变换以后的椭圆 36 M = matrix([[2, 1], [1, 2]]) # 2 × 2 的变换矩阵 37 clMat = plotCircle(cirMat, M) 38 39 # 将 M 矩阵进行 svd 分解 40 U, s, V = np.linalg.svd(M, full_matrices=True) 41 S = np.diag(s) 42 43 # SVD 矩阵对圆的变换 44 plotCircle(cirMat) 45 Tran1 = plotCircle(cirMat, V) 46 Tran2 = plotCircle(Tran1, S) 47 Tran3 = plotCircle(Tran2, U)
假设矩阵 A 的秩是 r, 那么对角线矩阵的秩也是 r (乘以酉矩阵不会改变矩阵的秩), 咱们假设:
那么, Ax = 0 的 null space 也就是解空间是什么呢?答案以下:
矩阵 A 的线性子空间是啥?设想有一个很高的矩阵 A, 它的列向量颇有可能不是正交的。对于任意一个坐标 x,矩阵 A 的线性子空间能够定义为:
这就是正定矩阵的对角化。计算过程以下:
Lanczos algorithm 是一种迭代的计算方法,没来得及细看。
感受 SVD 计算水很深,要用到的时候再看,如今暂不深刻了。
主成分分析常常用于减小数据集的维数,同时保持数据集中的对方差贡献最大的特征。假设上面的椭圆中(二维空间,两个坐标值)均匀分布了很是多的点,如何在一维空间(一个坐标值)里面就能最大程度将这些点区分开来呢?这时候就要用到 PCA:
能够看到,上图中将全部的点投影到 +45° 直线上,将二维空间映射到一维空间,能够最大程度地区分开这些点,即投影后的样本分布方差最大,这个方向就是 v1 向量的方向。就上图来讲,假设 100×2 的矩阵 X 表示样本点在平面上的坐标,将这些点投影到 v1 上保留最大的样本方差:
这样,就将 100 个 2 维空间的样本点压缩为 100 个 1 维空间的样本点,这里的列压缩其实是对特征进行了压缩, 而不是简单地丢弃。PCA 是否是只能在样本点个数大于特征个数的时候才能压缩呢?例如,如今 3 个 100 维特征的样本用 100×3 的矩阵表示,用 SVD 分解后能够获得三个矩阵的乘积,作以下变换:
一样也最大限度保留了主成分。
总结起来,一个矩阵 A, 若是想对行进行压缩并保留主成分,那么左乘 u1', 若是相对列进行压缩并保留主成分(让我联想起了稀疏表示),那么右乘 v1。
固然,上面是简单的保留第一个主成分,PCA的所有工做简单点说,就是对原始的空间中顺序地找一组相互正交的坐标轴,第一个轴是使得方差最大的,第二个轴是在与第一个轴正交的平面中使得方差最大的,第三个轴是在与第一、2个轴正交的平面中方差最大的,这样假设在N维空间中,咱们能够找到N个这样的坐标轴,咱们取前r个去近似这个空间,这样就从一个N维的空间压缩到r维的空间了,可是咱们选择的r个坐标轴可以使得空间的压缩使得数据的损失最小。
想法和 QR 分解的办法相似,主要是利用酉矩阵变换的长度不变性:
获得最优解是: