目录
一 .特征值分解(EVD-eigen value decomposition)
二 .奇异值分解(SVD-singular value decomposition)
前言
EVD分解要求 被分解矩阵 是实对称矩阵
SVD对被分解矩阵没有这个要求。
相当于一个从特殊到一般的过程。
一 .特征值分解(EVD-eigen value decomposition)
定义
在理角奇异值分解之前,需要先回顾一下特征值分解,如果矩阵A 是一个 m×m 的实对称矩阵
(即 ),那么它可以被分解成如下的形式
其中P是 标准正交 阵 (orthogonal) ,即, 是特征值。
回顾
线性代数( liner algebra) 中,定义 如果 , 那么就是特征值eigenvalue,是特征向量eigenvector。
其中 A 是n*n的实对称阵, 是数, 是n维列向量。
e.g.
then, 定义变形为 , 求此等式有非零解() 的特征值
那么只能是行列式 ( determinant ) ,
求得eigenvalue后,把eigenvalue 带入A 求得eigenvector。
二 .奇异值分解(SVD-singular value decomposition)
定义
有m rows * n cols的实数矩阵 A,分解为
其中 是左奇异和右奇异矩阵, 都是单位正交阵 :
奇异值矩阵 对角线上有值,称为奇异值,其它元素为0。形式如下:
对于奇异值分解,我们可以利用下面的图形表示,图中方块的颜色表示值的大小,颜色越浅,值越大。对于奇异值矩阵 ,只有其主对角线有奇异值,其余均为0。
求解
利用如下性质即可求解,这就是SVD的关键所在。
进一步, 和 也是实对称矩阵,利用EVD求解 和 以及 。注意 特征值最后要开方。
注意: 两者维数不同,但是对角线上的奇异值是相同的。
三 例子和应用
e.g.
为了进一步说明具体的计算过程,笔者使用eigen库实现和验证了SVD,代码如下。
其中mat33 指的是上图的 mat35指的是上图的 mat35 指的是上图的。
eigen代码实现
#include<iostream>
using namespace std;
#include<eigen3/Eigen/Core>
#include<eigen3/Eigen/Dense>
#include<eigen3/Eigen/SVD>
using namespace Eigen;
int main(){
Eigen::Matrix3d mat33=Eigen::Matrix3d::Zero();
//cout<<mat33<<endl;
mat33<<112,105,114,105,137,110,114,110,123;
for(int i=0;i<3;i++){
for(int j=0;j<3;j++)
cout<<mat33(i,j)<<" ";
cout<<endl;
}
Eigen::SelfAdjointEigenSolver<Eigen::Matrix3d> e_solver(mat33);
cout<<"Eigen33 values:"<<endl<<e_solver.eigenvalues()<<endl;
cout<<"Eigen33 vectors:"<<endl<<e_solver.eigenvectors()<<endl;
MatrixXf mat35(3,5);
mat35<< 1,5,7,6,1,2,1,10,4,4,3,6,7,5,2;
JacobiSVD<MatrixXf> svd35(mat35,ComputeThinU | ComputeThinV);
cout<<"svd35 values"<<endl<<svd35.singularValues()<<endl;
cout<<"svd35 U"<<endl<<svd35.matrixU()<<endl;
cout<<"svd35 V"<<endl<<svd35.matrixV()<<endl;
//cout<<mat35<<endl;
MatrixXf mat55(5,5);
mat55=mat35.transpose()*mat35;
cout<<mat55<<endl;
SelfAdjointEigenSolver<MatrixXf> eslover55(mat55);
cout<<"Eigen55 values"<<endl<<eslover55.eigenvalues()<<endl;
cout<<"Eigen55 vectors:"<<endl<<eslover55.eigenvectors()<<endl;
MatrixXf sigma(3,3);
sigma(0,0)=1.83;
sigma(1,1)=5.01;
sigma(2,2)=18.54;
cout<<sigma<<endl;
cout<<(sigma.inverse())*(svd35.matrixU().transpose())*mat35<<endl;
return 0;
}
完整工程传送门: https://download.csdn.net/download/bluenapa/11846085
使用EVD(特征值分解)的方法得
奇异值的平方 从小 到大排列
对应的U是
0.725779 0.405482 0.555725
-0.00401031 -0.805316 0.592832
-0.687917 0.432493 0.582855
奇异值的平方 前两项近似为0;
对应的V是
-0.652774 0 -0.73355 -0.0184451 0.188283
0.436243 -0.125973 -0.27392 -0.762547 0.370557
0.0661727 -0.476896 0.122583 0.436974 0.749812
-0.408706 0.54888 0.489968 -0.274509 0.465044
0.460606 0.674857 -0.363011 0.389718 0.220802
使用eigen封装的 SVD 方法得 的奇异值(开方后)为 从大到小排列
对应的 U是
-0.555725 -0.405482 -0.725779
-0.592832 0.805316 0.00401022
-0.582855 -0.432493 0.687917
对应的 V是
-0.188282 -0.018445 0.733548
-0.370558 -0.762548 0.27392
-0.749812 0.436973 -0.122584
-0.465043 -0.274508 -0.489968
-0.220803 0.389719 0.363014
注意:eigenvalue和eigenvector都是对应的,改变特征值的顺序时也要改变特征向量的顺序。
四 压缩比率 compress ration
选取k 个大奇异值以及这些对应的左右奇异向量逼近原图像,便可以共使用k(m+n+1) 个数值取代原来的m∗n 个图像数据。
所以压缩比率comprssion ratio为
拓展:PCA
PCA可以说是SVD的一个拓展,对SVD的一个封装。
参考:https://blog.csdn.net/chenaiyanmie/article/details/80011244