1、奇异值分解基础知识
特征值分解提取矩阵特征只适用于方阵,对于N * M的矩阵要用奇异值分解:
假设A是一个N * M的矩阵,奇异值分解得到的U是一个N * N的方阵(里面的向量是正交的,U里面的向量称为左奇异向量),Σ是一个N * M的矩阵(除了对角线的元素都是0,对角线上的元素称为奇异值),VT(V的转置)是一个N * N的矩阵,里面的向量也是正交的,V里面的向量称为右奇异向量)。
通过奇异值如何提取特征值呢?
首先,将一个矩阵A的转置乘以 A,将会得到一个方阵,用这个方阵求特征值可以得到:
v右奇异向量,σ是奇异值,u是左奇异向量。
奇异值σ跟特征值类似,在矩阵Σ中也是从大到小排列,而且σ的减少特别的快,在很多情况下,前10%甚至1%的奇异值的和就占了全部的奇异值之和的99%以上了。也就是说,我们也可以用前r大的奇异值来近似描述矩阵,这里定义一下部分奇异值分解:
r是一个远小于m、n的数。右边的三个矩阵相乘的结果将会是一个接近于A的矩阵,在这儿,r越接近于n,则相乘的结果越接近于A。而这三个矩阵的面积之和(在存储观点来说,矩阵面积越小,存储量就越小)要远远小于原始的矩阵A,如果想要压缩空间来表示原矩阵A,存下这里的三个矩阵:U、Σ、V就可以。
2、Java实现:
还是用jama包实现。
1)测试类:
package sk.ml;
import Jama.SingularValueDecomposition;
import Jama.Matrix;
public class QRTest {
//矩阵特征分解
public static void main(String argv[]){
double[] columnwise = {1.,2.,3.,4.,5.,6.,7.,8.,9.,10.,11.,12.};
Matrix A = new Matrix(columnwise,4);//构造矩阵
A.print(A.getColumnDimension(), A.getRowDimension());
SingularValueDecomposition SVD = A.svd();
Matrix S = SVD.getS();//奇异值
Matrix V = SVD.getV();//右奇异向量
Matrix U = SVD.getU();//左奇异向量
S.print(S.getColumnDimension(), S.getRowDimension());
V.print(V.getColumnDimension(), V.getRowDimension());
U.print(U.getColumnDimension(), U.getRowDimension());
}
}
2)SingularValueDecomposition类源码研究
package Jama;
import Jama.util.*;
/** Singular Value Decomposition.
<P>
For an m-by-n matrix A with m >= n, the singular value decomposition is
an m-by-n orthogonal matrix U, an n-by-n diagonal matrix S, and
an n-by-n orthogonal matrix V so that A = U*S*V'.
<P>
The singular values, sigma[k] = S[k][k], are ordered so that
sigma[0] >= sigma[1] >= ... >= sigma[n-1].
<P>
The singular value decompostion always exists, so