简介
奇异值分解(singular Value Decomposition),简称SVD,线性代数中矩阵分解的方法。假如有一个矩阵A,对它进行奇异值分解,可以得到三个矩阵:
这三个矩阵的大小:
矩阵sigma(即上图U和V中间的矩阵)除了对角元素不为0,其他元素都为0,并且对角元素是从大到小排列的,前面的元素比较大,后面的很多元素接近0。这些对角元素就是奇异值。
sigma中有n个奇异值,但是由于排在后面的很多接近0,所以我们可以仅保留比较大的r个奇异值:
实际应用中,我们仅需保留着三个比较小的矩阵,就能表示A,不仅节省存储量,在计算的时候更是减少了计算量。SVD在信息检索(隐性语义索引)、图像压缩、推荐系统、金融等领域都有应用。
在主成分分析中,我是通过特征值分解的方法来实现PCA的,除了特征值分解,还可以用奇异值分解来实现PCA。特征值和奇异值二者之间是有关系的:上面我们由矩阵A获得了奇异值sigma(i),假如方阵A*A’的特征值为lamda(i),则:sigma(i)^2=lamda(i)。可以发现,求特征值必须要求矩阵是方阵,而求奇异值对任意矩阵都可以,因此PCA的实现其实用SVD的更多,在scikit-learn中,PCA算法其实也是通过SVD来实现的。
python中实现SVD
numpy中的linalg已经实现了SVD,可以直接调用
1 | 1,2,3],[4,5,6]]) A=mat([[ |
有一点需要注意,sigma本来应该跟A矩阵的大小2*3一样,但linalg.svd()只返回了一个行向量的sigma,并且只有2个奇异值(本来应该有3个),这是因为第三个奇异值为0,舍弃掉了。之所以这样做,是因为当A是非常大的矩阵时,只返回奇异值可以节省很大的存储空间。当然,如果我们要重构A,就必须先将sigma转化为矩阵。
Matlab实现SVD
1 | [u,s,v] = svd(f); |
注意:Python中的SVD和matlab中的SVD中最后一个矩阵v互为转置关系