特征值分解、奇异值分解、PCA概念整理

标签: PCA特征值及向量奇异值QR算法
2014-01-18 14:21 16402人阅读 评论(5) 收藏 举报

本文章已收录于:
分类:
机器学习(9)

作者同类文章X

版权声明:本文为博主原创文章,未经博主允许不得转载。

本文将分别介绍特征值分解、奇异值分解、及PCA的相关理论概念。

文章末尾将给出Householder矩阵变换、QR算法求解特征值、特征向量的代码

其中,特征值分解、奇异值分解的相关内容,转载自:

http://www.cnblogs.com/LeftNotEasy/archive/2011/01/19/svd-and-applications.html

考虑到本文50%以上的部分不是那个哥们的博客原文,所以我搞成原创标题了。。。。

一、特征值与特征向量的几何意义

1.     矩阵乘法

在介绍特征值与特征向量的几何意义之前,先介绍矩阵乘法的几何意义。

矩阵乘法对应了一个变换,是把任意一个向量变成另一个方向或长度的新向量。在这个变化过程中,原向量主要发生旋转、伸缩的变化。如果矩阵对某些向量只发生伸缩变换,不产生旋转效果,那么这些向量就称为这个矩阵的特征向量,伸缩的比例就是特征值。

比如:,它对应的线性变换是下面的形式形式:

因为,这个矩阵乘以一个向量(x,y)的结果是:。由于矩阵M是对称的,所以这个变换是一个对 x , y 轴的一个拉伸变换。【当M中元素值大于1时,是拉伸;当值小于1时,是缩短】

那么如果矩阵M不是对称的,比如:,它所描述的变换如下图所示:

这其实是在平面上对一个轴进行的拉伸变换【如蓝色箭头所示】,在图中蓝色箭头是一个最主要的变化方向。变化方向可能有不止一个,但如果我们想要描述好一个变换,那我们就描述好这个变换主要的变化方向就好了。

2.     特征值分解与特征向量

如果说一个向量v是方阵A的特征向量,将一定可以表示成下面的形式:

λ为特征向量 v 对应的特征值。特征值分解是将一个矩阵分解为如下形式:

其中,Q是这个矩阵A的特征向量组成的矩阵,Σ是一个对角矩阵,每一个对角线元素就是一个特征值,里面的特征值是由大到小排列的,这些特征值所对应的特征向量就是描述这个矩阵变化方向(从主要的变化到次要的变化排列)。也就是说矩阵A的信息可以由其特征值和特征向量表示。

对于矩阵为高维的情况下,那么这个矩阵就是高维空间下的一个线性变换。可以想象,这个变换也同样有很多的变换方向,我们通过特征值分解得到的前N个特征向量,那么就对应了这个矩阵最主要的N个变化方向。我们利用这前N个变化方向,就可以近似这个矩阵(变换)。

总结一下,特征值分解可以得到特征值与特征向量,特征值表示的是这个特征到底有多重要,而特征向量表示这个特征是什么。不过,特征值分解也有很多的局限,比如说变换的矩阵必须是方阵。

二、奇异值分解

1.     奇异值

特征值分解是一个提取矩阵特征很不错的方法,但是它只是对方阵而言的,在现实的世界中,我们看到的大部分矩阵都不是方阵,比如说有N个学生,每个学生有M科成绩,这样形成的一个N * M的矩阵就不可能是方阵,我们怎样才能描述这样普通的矩阵呢的重要特征呢?奇异值分解可以用来干这个事情,奇异值分解是一个能适用于任意的矩阵的一种分解的方法:

分解形式:

假设A是一个M * N的矩阵,那么得到的U是一个M * M的方阵(称为左奇异向量),Σ是一个M * N的矩阵(除了对角线的元素都是0,对角线上的元素称为奇异值),VT(V的转置)是一个N * N的矩阵(称为右奇异向量)。

2.     奇异值与特征值

那么奇异值和特征值是怎么对应起来的呢?我们将一个矩阵A的转置乘以 A,并对(AAT)求特征值,则有下面的形式:

这里V就是上面的右奇异向量,另外还有:

这里的σ就是奇异值,u就是上面说的左奇异向量。【证明那个哥们也没给】

奇异值σ跟特征值类似,在矩阵Σ中也是从大到小排列,而且σ的减少特别的快,在很多情况下,前10%甚至1%的奇异值的和就占了全部的奇异值之和的99%以上了。也就是说,我们也可以用前r( r远小于m、n )个的奇异值来近似描述矩阵,即部分奇异值分解:

右边的三个矩阵相乘的结果将会是一个接近于A的矩阵,在这儿,r越接近于n,则相乘的结果越接近于A。

三、PCA主成份分析

主成分分析(PrincipalComponents Analysis。即PCA,也称为K-L变换),是图像压缩中的一种最优正交变换。PCA用于统计特征提取构成了子空间法模式识别的基础。它从图像整体代数特征出发,基于图像的总体信息进行分类识别。PCA的核心思想是利用较少数量的特征对样本进行描述以达到降低特征空间维数的目的。

1.  PCA理论

给定一副N*N大小图像,将它表示成一个N2*1维向量,向量中元素为像素点灰度,按行存储,如下列公式分别表示第i张图片和n张图片平均值:

令N2*n矩阵X为:

注意,矩阵减去平均值相当于将坐标系原点移动到平均值位置。

设Q=XXT,则Q是一个N2* N2矩阵:

,Q是方阵

,Q是对称矩阵。

,Q被成为协方差矩阵,

,Q的数据量非常庞大

那么,X中的每个元素xj可以被如下表达:

其中,ei是Q中非零特征值对应的特征向量。由特征向量e1,e2,…,en组成的空间叫做张成特征空间。对于N*N图像,e1,e2,…,en是N2*1维相互正交的向量。尺度gji是xj在空间中的坐标。

2.  实现PCA

为了降维,可以对特征值设定阈值或按照其他准则,寻找协方差矩阵Q中前k个特征向量。这里Q十分庞大,对于一副256*256的图像,Q的大小为65536*65536!替代方案是,考虑矩阵

.P和Q都是对称矩阵

.P≠QT

.Q的大小是N2*N2,而P大小为n*n

.n为训练样本图像数量,通常n<<N

设e是矩阵P的特征值λ对应的特征向量,则有:

这里,X*e也是矩阵Q的特征值λ对应的特征向量【这是用求特征值分解方法,下面介绍用SVD方法】

3.  PCA与奇异值分解SVD

任何一个m*n矩阵都能进行奇异值分解,拆分为3个矩阵相乘的形式。由于SVD得出的奇异向量也是从奇异值由大到小排列的,按PCA的观点来看,就是方差最大的坐标轴就是第一个奇异向量,方差次大的坐标轴就是第二个奇异向量…。我们可以对Q进行奇异值分解。

.U就是QQT的特征向量

.V就是QTQ的特征向量

.D中奇异值的平方就是QQT和QTQ的特征值

=======================================================================================================================

上面讲了一大堆,就是为了下一篇PCA人脸识别做铺垫的,给你一副图像,要从图像库中得到匹配的图像,怎么弄?如果是两两做像素点比较是不可能完成的任务,时间上废掉了。如果用其他特征点代替也许可以,但容易漏检吧,这边不扩展。我们必须对图像数据的协方差矩阵进行降维,所以用到了PCA。

而具体如何实现PCA呢?关键是特征值及相应特征向量的求取。matlab有个eig函数,OpenCV也有相应的函数。由于不想被别人牵制,我自己查了资料,发现QR算法可以用来求实对称矩阵的全部特征值和特征向量。【雅可比算法也可以,就是速度太慢了;而上面介绍的SVD实现PCA还没见过,文献上说SVD和PCA是等价的】

=======================================================================================================================

以下内容,来自《C常用算法程序集第二版》,这绝对是搞科研的好书!

在用QR算法求解特征值和向量之前,必须将实对称矩阵转化为三对角矩阵。【由于我们的协方差矩阵是实对称矩阵,因此不用转化为Hessen berg矩阵,QR算法是一个迭代的过程,具体算法太长了,我不贴出来了,有需要的,自己去下载这本书的PDF文档或其他资料】

1.约化对称矩阵为三对角矩阵的Householder变换法:

例:

【其他高维矩阵也行,大家可以把数据存在txt文本中,然后读取进来】

代码:

[cpp] view plaincopy print?
  1. // HouseHolder_Transform.cpp : 定义控制台应用程序的入口点。
  2. //
  3. #include "stdafx.h"
  4. #include "math.h"
  5. void cstrq(double a[],int n,double q[],double b[],double c[]);
  6. int _tmain(int argc, _TCHAR* argv[])
  7. {
  8. int i,j;
  9. static double b[5],c[5],q[25];
  10. static double a[25] = {10.0,1.0,2.0,3.0,4.0,1.0,9.0,-1.0,2.0,-3.0,2.0,-1.0,7.0,3.0,-5.0,3.0,2.0,3.0,12.0,-1.0,4.0,-3.0,-5.0,-1.0,15.0};
  11. cstrq(a,5,q,b,c);
  12. printf("MAT A is:\n");
  13. for (i=0;i<5;i++)
  14. {
  15. for (j=0;j<5;j++)
  16. {
  17. printf("%13.7e ",a[i*5+j]);
  18. }
  19. printf("\n");
  20. }
  21. printf("\n");
  22. printf("MAT Q is:\n");
  23. for (i=0;i<5;i++)
  24. {
  25. for (j=0;j<5;j++)
  26. {
  27. printf("%13.7e ",q[i*5+j]);
  28. }
  29. printf("\n");
  30. }
  31. printf("\n");
  32. printf("MAT B is:\n");
  33. for (i=0;i<5;i++)
  34. {
  35. printf("%13.7e ",b[i]);
  36. }
  37. printf("\n\n");
  38. printf("MAT C is:\n");
  39. for (i=0;i<5;i++)
  40. {
  41. printf("%13.7e ",c[i]);
  42. }
  43. printf("\n\n");
  44. return 0;
  45. }
  46. void cstrq(double a[],int n,double q[],double b[],double c[])
  47. {
  48. int i,j,k,u,v;
  49. double h,f,g,h2;
  50. for (i=0; i<=n-1; i++)
  51. for (j=0; j<=n-1; j++)
  52. { u=i*n+j; q[u]=a[u];}
  53. for (i=n-1; i>=1; i--)
  54. { h=0.0;
  55. if (i>1)
  56. for (k=0; k<=i-1; k++)
  57. { u=i*n+k; h=h+q[u]*q[u];}
  58. if (h+1.0==1.0)
  59. { c[i]=0.0;
  60. if (i==1) c[i]=q[i*n+i-1];
  61. b[i]=0.0;
  62. }
  63. else
  64. { c[i]=sqrt(h);
  65. u=i*n+i-1;
  66. if (q[u]>0.0) c[i]=-c[i];
  67. h=h-q[u]*c[i];
  68. q[u]=q[u]-c[i];
  69. f=0.0;
  70. for (j=0; j<=i-1; j++)
  71. { q[j*n+i]=q[i*n+j]/h;
  72. g=0.0;
  73. for (k=0; k<=j; k++)
  74. g=g+q[j*n+k]*q[i*n+k];
  75. if (j+1<=i-1)
  76. for (k=j+1; k<=i-1; k++)
  77. g=g+q[k*n+j]*q[i*n+k];
  78. c[j]=g/h;
  79. f=f+g*q[j*n+i];
  80. }
  81. h2=f/(h+h);
  82. for (j=0; j<=i-1; j++)
  83. { f=q[i*n+j];
  84. g=c[j]-h2*f;
  85. c[j]=g;
  86. for (k=0; k<=j; k++)
  87. { u=j*n+k;
  88. q[u]=q[u]-f*c[k]-g*q[i*n+k];
  89. }
  90. }
  91. b[i]=h;
  92. }
  93. }
  94. for (i=0; i<=n-2; i++) c[i]=c[i+1];
  95. c[n-1]=0.0;
  96. b[0]=0.0;
  97. for (i=0; i<=n-1; i++)
  98. { if ((b[i]!=0.0)&&(i-1>=0))
  99. for (j=0; j<=i-1; j++)
  100. { g=0.0;
  101. for (k=0; k<=i-1; k++)
  102. g=g+q[i*n+k]*q[k*n+j];
  103. for (k=0; k<=i-1; k++)
  104. { u=k*n+j;
  105. q[u]=q[u]-g*q[k*n+i];
  106. }
  107. }
  108. u=i*n+i;
  109. b[i]=q[u]; q[u]=1.0;
  110. if (i-1>=0)
  111. for (j=0; j<=i-1; j++)
  112. { q[i*n+j]=0.0; q[j*n+i]=0.0;}
  113. }
  114. return;
  115. }

// HouseHolder_Transform.cpp : 定义控制台应用程序的入口点。
//#include "stdafx.h"
#include "math.h"void cstrq(double a[],int n,double q[],double b[],double c[]);int _tmain(int argc, _TCHAR* argv[])
{int i,j;static double b[5],c[5],q[25];static double a[25] = {10.0,1.0,2.0,3.0,4.0,1.0,9.0,-1.0,2.0,-3.0,2.0,-1.0,7.0,3.0,-5.0,3.0,2.0,3.0,12.0,-1.0,4.0,-3.0,-5.0,-1.0,15.0};cstrq(a,5,q,b,c);printf("MAT A is:\n");for (i=0;i<5;i++){for (j=0;j<5;j++){printf("%13.7e ",a[i*5+j]);}printf("\n");}printf("\n");printf("MAT Q is:\n");for (i=0;i<5;i++){for (j=0;j<5;j++){printf("%13.7e ",q[i*5+j]);}printf("\n");}printf("\n");printf("MAT B is:\n");for (i=0;i<5;i++){printf("%13.7e ",b[i]);}printf("\n\n");printf("MAT C is:\n");for (i=0;i<5;i++){printf("%13.7e ",c[i]);}printf("\n\n");return 0;
}void cstrq(double a[],int n,double q[],double b[],double c[])
{int i,j,k,u,v;double h,f,g,h2;for (i=0; i<=n-1; i++)for (j=0; j<=n-1; j++){ u=i*n+j; q[u]=a[u];}for (i=n-1; i>=1; i--){ h=0.0;if (i>1)for (k=0; k<=i-1; k++){ u=i*n+k; h=h+q[u]*q[u];}if (h+1.0==1.0){ c[i]=0.0;if (i==1) c[i]=q[i*n+i-1];b[i]=0.0;}else{ c[i]=sqrt(h);u=i*n+i-1;if (q[u]>0.0) c[i]=-c[i];h=h-q[u]*c[i];q[u]=q[u]-c[i];f=0.0;for (j=0; j<=i-1; j++){ q[j*n+i]=q[i*n+j]/h;g=0.0;for (k=0; k<=j; k++)g=g+q[j*n+k]*q[i*n+k];if (j+1<=i-1)for (k=j+1; k<=i-1; k++)g=g+q[k*n+j]*q[i*n+k];c[j]=g/h;f=f+g*q[j*n+i];}h2=f/(h+h);for (j=0; j<=i-1; j++){ f=q[i*n+j];g=c[j]-h2*f;c[j]=g;for (k=0; k<=j; k++){ u=j*n+k;q[u]=q[u]-f*c[k]-g*q[i*n+k];}}b[i]=h;}}for (i=0; i<=n-2; i++) c[i]=c[i+1];c[n-1]=0.0;b[0]=0.0;for (i=0; i<=n-1; i++){ if ((b[i]!=0.0)&&(i-1>=0))for (j=0; j<=i-1; j++){ g=0.0;for (k=0; k<=i-1; k++)g=g+q[i*n+k]*q[k*n+j];for (k=0; k<=i-1; k++){ u=k*n+j;q[u]=q[u]-g*q[k*n+i];}}u=i*n+i;b[i]=q[u]; q[u]=1.0;if (i-1>=0)for (j=0; j<=i-1; j++){ q[i*n+j]=0.0; q[j*n+i]=0.0;}}return;
}

计算结果:

即上述计算结果返回的三对角阵T为:

2.下面,我们将在三对角矩阵的基础上使用QR算法计算全部特征值和特征向量

例,同样对上面那个5阶矩阵,先求三对角矩阵,再求其全部特征值和特征向量

最大迭代次数为60,误差为0.000001

代码:

[cpp] view plaincopy print?
  1. #include "stdafx.h"
  2. #include "math.h"
  3. void cstrq(double a[],int n,double q[],double b[],double c[]);
  4. int csstq(int n,double b[],double c[],double q[],double eps,int l);
  5. int _tmain(int argc, _TCHAR* argv[])
  6. {
  7. int i,j,k,l=60;
  8. static double b[5],c[5],q[25];
  9. static double a[25] = {10.0,1.0,2.0,3.0,4.0,1.0,9.0,-1.0,2.0,-3.0,2.0,-1.0,7.0,3.0,-5.0,3.0,2.0,3.0,12.0,-1.0,4.0,-3.0,-5.0,-1.0,15.0};
  10. double eps = 0.000001;
  11. cstrq(a,5,q,b,c);
  12. k = csstq(5,b,c,q,eps,l);
  13. printf("MAT A is:\n");
  14. for (i=0;i<5;i++)
  15. {
  16. for (j=0;j<5;j++)
  17. {
  18. printf("%13.7e ",a[i*5+j]);
  19. }
  20. printf("\n");
  21. }
  22. printf("\n");
  23. printf("MAT B is:\n");
  24. for (i=0;i<5;i++)
  25. {
  26. printf("%13.7e ",b[i]);
  27. }
  28. printf("\n\n");
  29. printf("MAT Q is:\n");
  30. for (i=0;i<5;i++)
  31. {
  32. for (j=0;j<5;j++)
  33. {
  34. printf("%13.7e ",q[i*5+j]);
  35. }
  36. printf("\n");
  37. }
  38. printf("\n");
  39. return 0;
  40. }
  41. void cstrq(double a[],int n,double q[],double b[],double c[])
  42. {
  43. int i,j,k,u,v;
  44. double h,f,g,h2;
  45. for (i=0; i<=n-1; i++)
  46. for (j=0; j<=n-1; j++)
  47. { u=i*n+j; q[u]=a[u];}
  48. for (i=n-1; i>=1; i--)
  49. { h=0.0;
  50. if (i>1)
  51. for (k=0; k<=i-1; k++)
  52. { u=i*n+k; h=h+q[u]*q[u];}
  53. if (h+1.0==1.0)
  54. { c[i]=0.0;
  55. if (i==1) c[i]=q[i*n+i-1];
  56. b[i]=0.0;
  57. }
  58. else
  59. { c[i]=sqrt(h);
  60. u=i*n+i-1;
  61. if (q[u]>0.0) c[i]=-c[i];
  62. h=h-q[u]*c[i];
  63. q[u]=q[u]-c[i];
  64. f=0.0;
  65. for (j=0; j<=i-1; j++)
  66. { q[j*n+i]=q[i*n+j]/h;
  67. g=0.0;
  68. for (k=0; k<=j; k++)
  69. g=g+q[j*n+k]*q[i*n+k];
  70. if (j+1<=i-1)
  71. for (k=j+1; k<=i-1; k++)
  72. g=g+q[k*n+j]*q[i*n+k];
  73. c[j]=g/h;
  74. f=f+g*q[j*n+i];
  75. }
  76. h2=f/(h+h);
  77. for (j=0; j<=i-1; j++)
  78. { f=q[i*n+j];
  79. g=c[j]-h2*f;
  80. c[j]=g;
  81. for (k=0; k<=j; k++)
  82. { u=j*n+k;
  83. q[u]=q[u]-f*c[k]-g*q[i*n+k];
  84. }
  85. }
  86. b[i]=h;
  87. }
  88. }
  89. for (i=0; i<=n-2; i++) c[i]=c[i+1];
  90. c[n-1]=0.0;
  91. b[0]=0.0;
  92. for (i=0; i<=n-1; i++)
  93. { if ((b[i]!=0.0)&&(i-1>=0))
  94. for (j=0; j<=i-1; j++)
  95. { g=0.0;
  96. for (k=0; k<=i-1; k++)
  97. g=g+q[i*n+k]*q[k*n+j];
  98. for (k=0; k<=i-1; k++)
  99. { u=k*n+j;
  100. q[u]=q[u]-g*q[k*n+i];
  101. }
  102. }
  103. u=i*n+i;
  104. b[i]=q[u]; q[u]=1.0;
  105. if (i-1>=0)
  106. for (j=0; j<=i-1; j++)
  107. { q[i*n+j]=0.0; q[j*n+i]=0.0;}
  108. }
  109. return;
  110. }
  111. int csstq(int n,double b[],double c[],double q[],double eps,int l)
  112. {
  113. int i,j,k,m,it,u,v;
  114. double d,f,h,g,p,r,e,s;
  115. c[n-1]=0.0; d=0.0; f=0.0;
  116. for (j=0; j<=n-1; j++)
  117. { it=0;
  118. h=eps*(fabs(b[j])+fabs(c[j]));
  119. if (h>d) d=h;
  120. m=j;
  121. while ((m<=n-1)&&(fabs(c[m])>d)) m=m+1;
  122. if (m!=j)
  123. { do
  124. { if (it==l)
  125. { printf("fail\n");
  126. return(-1);
  127. }
  128. it=it+1;
  129. g=b[j];
  130. p=(b[j+1]-g)/(2.0*c[j]);
  131. r=sqrt(p*p+1.0);
  132. if (p>=0.0) b[j]=c[j]/(p+r);
  133. else b[j]=c[j]/(p-r);
  134. h=g-b[j];
  135. for (i=j+1; i<=n-1; i++)
  136. b[i]=b[i]-h;
  137. f=f+h; p=b[m]; e=1.0; s=0.0;
  138. for (i=m-1; i>=j; i--)
  139. { g=e*c[i]; h=e*p;
  140. if (fabs(p)>=fabs(c[i]))
  141. { e=c[i]/p; r=sqrt(e*e+1.0);
  142. c[i+1]=s*p*r; s=e/r; e=1.0/r;
  143. }
  144. else
  145. { e=p/c[i]; r=sqrt(e*e+1.0);
  146. c[i+1]=s*c[i]*r;
  147. s=1.0/r; e=e/r;
  148. }
  149. p=e*b[i]-s*g;
  150. b[i+1]=h+s*(e*g+s*b[i]);
  151. for (k=0; k<=n-1; k++)
  152. { u=k*n+i+1; v=u-1;
  153. h=q[u]; q[u]=s*q[v]+e*h;
  154. q[v]=e*q[v]-s*h;
  155. }
  156. }
  157. c[j]=s*p; b[j]=e*p;
  158. }
  159. while (fabs(c[j])>d);
  160. }
  161. b[j]=b[j]+f;
  162. }
  163. for (i=0; i<=n-1; i++)
  164. { k=i; p=b[i];
  165. if (i+1<=n-1)
  166. { j=i+1;
  167. while ((j<=n-1)&&(b[j]<=p))
  168. { k=j; p=b[j]; j=j+1;}
  169. }
  170. if (k!=i)
  171. { b[k]=b[i]; b[i]=p;
  172. for (j=0; j<=n-1; j++)
  173. { u=j*n+i; v=j*n+k;
  174. p=q[u]; q[u]=q[v]; q[v]=p;
  175. }
  176. }
  177. }
  178. return(1);
  179. }

#include "stdafx.h"
#include "math.h"void cstrq(double a[],int n,double q[],double b[],double c[]);
int csstq(int n,double b[],double c[],double q[],double eps,int l);int _tmain(int argc, _TCHAR* argv[])
{int i,j,k,l=60;static double b[5],c[5],q[25];static double a[25] = {10.0,1.0,2.0,3.0,4.0,1.0,9.0,-1.0,2.0,-3.0,2.0,-1.0,7.0,3.0,-5.0,3.0,2.0,3.0,12.0,-1.0,4.0,-3.0,-5.0,-1.0,15.0};double eps = 0.000001;cstrq(a,5,q,b,c);k = csstq(5,b,c,q,eps,l);printf("MAT A is:\n");for (i=0;i<5;i++){for (j=0;j<5;j++){printf("%13.7e ",a[i*5+j]);}printf("\n");}printf("\n");printf("MAT B is:\n");for (i=0;i<5;i++){printf("%13.7e ",b[i]);}printf("\n\n");printf("MAT Q is:\n");for (i=0;i<5;i++){for (j=0;j<5;j++){printf("%13.7e ",q[i*5+j]);}printf("\n");}printf("\n");return 0;
}void cstrq(double a[],int n,double q[],double b[],double c[])
{int i,j,k,u,v;double h,f,g,h2;for (i=0; i<=n-1; i++)for (j=0; j<=n-1; j++){ u=i*n+j; q[u]=a[u];}for (i=n-1; i>=1; i--){ h=0.0;if (i>1)for (k=0; k<=i-1; k++){ u=i*n+k; h=h+q[u]*q[u];}if (h+1.0==1.0){ c[i]=0.0;if (i==1) c[i]=q[i*n+i-1];b[i]=0.0;}else{ c[i]=sqrt(h);u=i*n+i-1;if (q[u]>0.0) c[i]=-c[i];h=h-q[u]*c[i];q[u]=q[u]-c[i];f=0.0;for (j=0; j<=i-1; j++){ q[j*n+i]=q[i*n+j]/h;g=0.0;for (k=0; k<=j; k++)g=g+q[j*n+k]*q[i*n+k];if (j+1<=i-1)for (k=j+1; k<=i-1; k++)g=g+q[k*n+j]*q[i*n+k];c[j]=g/h;f=f+g*q[j*n+i];}h2=f/(h+h);for (j=0; j<=i-1; j++){ f=q[i*n+j];g=c[j]-h2*f;c[j]=g;for (k=0; k<=j; k++){ u=j*n+k;q[u]=q[u]-f*c[k]-g*q[i*n+k];}}b[i]=h;}}for (i=0; i<=n-2; i++) c[i]=c[i+1];c[n-1]=0.0;b[0]=0.0;for (i=0; i<=n-1; i++){ if ((b[i]!=0.0)&&(i-1>=0))for (j=0; j<=i-1; j++){ g=0.0;for (k=0; k<=i-1; k++)g=g+q[i*n+k]*q[k*n+j];for (k=0; k<=i-1; k++){ u=k*n+j;q[u]=q[u]-g*q[k*n+i];}}u=i*n+i;b[i]=q[u]; q[u]=1.0;if (i-1>=0)for (j=0; j<=i-1; j++){ q[i*n+j]=0.0; q[j*n+i]=0.0;}}return;
}int csstq(int n,double b[],double c[],double q[],double eps,int l)
{int i,j,k,m,it,u,v;double d,f,h,g,p,r,e,s;c[n-1]=0.0; d=0.0; f=0.0;for (j=0; j<=n-1; j++){ it=0;h=eps*(fabs(b[j])+fabs(c[j]));if (h>d) d=h;m=j;while ((m<=n-1)&&(fabs(c[m])>d)) m=m+1;if (m!=j){ do{ if (it==l){ printf("fail\n");return(-1);}it=it+1;g=b[j];p=(b[j+1]-g)/(2.0*c[j]);r=sqrt(p*p+1.0);if (p>=0.0) b[j]=c[j]/(p+r);else b[j]=c[j]/(p-r);h=g-b[j];for (i=j+1; i<=n-1; i++)b[i]=b[i]-h;f=f+h; p=b[m]; e=1.0; s=0.0;for (i=m-1; i>=j; i--){ g=e*c[i]; h=e*p;if (fabs(p)>=fabs(c[i])){ e=c[i]/p; r=sqrt(e*e+1.0);c[i+1]=s*p*r; s=e/r; e=1.0/r;}else{ e=p/c[i]; r=sqrt(e*e+1.0);c[i+1]=s*c[i]*r;s=1.0/r; e=e/r;}p=e*b[i]-s*g;b[i+1]=h+s*(e*g+s*b[i]);for (k=0; k<=n-1; k++){ u=k*n+i+1; v=u-1;h=q[u]; q[u]=s*q[v]+e*h;q[v]=e*q[v]-s*h;}}c[j]=s*p; b[j]=e*p;}while (fabs(c[j])>d);}b[j]=b[j]+f;}for (i=0; i<=n-1; i++){ k=i; p=b[i];if (i+1<=n-1){ j=i+1;while ((j<=n-1)&&(b[j]<=p)){ k=j; p=b[j]; j=j+1;}}if (k!=i){ b[k]=b[i]; b[i]=p;for (j=0; j<=n-1; j++){ u=j*n+i; v=j*n+k;p=q[u]; q[u]=q[v]; q[v]=p;}}}return(1);
}

这里,又把householder贴了一遍。。。

计算结果:

这里,我们要注意:

数组q中第j列为数组b中第j个特征值对应的特征向量

5
0
  • 上一篇Delaunay 三角网格学习
  • 下一篇PCA人脸识别学习及C语言实现

我的同类文章

机器学习(9)
http://blog.csdn.net

  • Gauss-Newton算法学习2016-06-08阅读2927
  • 机器学习之旅---奇异值分解2014-11-22阅读2946
  • 机器学习之旅---logistic回归2014-10-12阅读4802
  • 离散随机线性系统的卡尔曼滤波器基本原理及实现2014-06-13阅读5079
  • SVM理论部分介绍2013-12-28阅读2716
  • 《Master Opencv...读书笔记》非刚性人脸跟踪 III2015-02-28阅读3040
  • 机器学习之旅---SVM分类器2014-11-07阅读27607
  • 机器学习之旅---朴素贝叶斯分类器2014-09-24阅读2372
  • matlab体验svm算法【非实现】2013-12-30阅读4855

特征值 奇异值分解 概念整理相关推荐

  1. AIFramework基本概念整理

    AIFramework基本概念整理 本文介绍: • 对天元 MegEngine 框架中的 Tensor, Operator, GradManager 等基本概念有一定的了解: • 对深度学习中的前向传 ...

  2. 区块链中的基本概念整理

    区块链中的基本概念整理 区块链本身是由多种技术集合而成,涉及了多方面的内容,而在其组合应用的过程中,同时也产生了很多新的概念.对于这些概念的整理和理解,有助于更加深刻的理解区块链的本质,也可以指导我们 ...

  3. 电分、模电、数电总复习之爱课堂题目概念整理

    本文模电数电部分转载自博客园_模电数电爱课堂概念题整理 模电.数电总复习之爱课堂题目概念整理 电分总复习之爱课堂题目概念整理(原创)(不定期更新) 模电总复习之爱课堂题目概念整理 Chapter 1 ...

  4. SR领域概念整理个人笔记

    概念整理(持更) 1. CV注意力机制 https://jishuin.proginn.com/p/763bfbd3296c 空间注意力模块:特征图每个位置进行attention调整,二维调整 通道注 ...

  5. 【jeecg-boot项目开发crm】:平台技术点——day05【Java定时任务解决方案:九、触发器,调度器概念整理】:图灵课堂

    九.触发器,调度器概念整理 1 触发器的优先级 1. 1判断错过触发的条件和产生的原因 1.2错过触发之后要怎么处理呢[下面给出策略] 默认使用的策略: SimpleTrigger[常用]: new* ...

  6. 特征值分解、奇异值分解、PCA概念整理(转载)

    版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/jinshengtao/article/details/18448355 本文将分别介绍特征值分解.奇 ...

  7. 特征值分解、奇异值分解、PCA概念整理

    本文将分别介绍特征值分解.奇异值分解.及PCA的相关理论概念. 文章末尾将给出Householder矩阵变换.QR算法求解特征值.特征向量的代码 其中,特征值分解.奇异值分解的相关内容,转载自: ht ...

  8. 交叉熵(cross entropy)概念整理

    网上写得实在是太乱,整理下: 交叉熵函数: H(p,q)=Ep[−logq]=−∑x∈χp(x)logq(x)①H(p,q)=E_p[-log\ q]=-\sum_{x\in \chi}p(x)log ...

  9. IIS Web 服务器/ASP.NET 运行原理基本知识概念整理

    前言: 记录 IIS 相关的笔记还是从公司笔试考核题开始的,问 Application Pool 与 AppDomain 的区别? 促使我对进程池进了知识的学习,所以记录一下学习的笔记. 我们知道现在 ...

最新文章

  1. asp.net中使用窗体身份验证
  2. HashMap的负载因子为什么默认是0.75
  3. 中文按拼音首字母排序的C++实现方案
  4. Java实例开发教程:SpringBoot开发案例
  5. 本地仓库的基本操作与概念——Git的学习与使用(三)
  6. SYNPROXY:廉价的抗 DoS 攻击方案
  7. 电脑桌面天气计算机备忘录,备忘录怎么添加到桌面,桌面备忘录小工具
  8. 私服脚本制作教程......
  9. 高频直流电源在整改、降压和作用方面解决方案
  10. 谷歌浏览器使用复制的功能
  11. 学习OpenCV(中文版)
  12. Web前端——jQuery库
  13. Springcloud之OAuth2
  14. html 状态栏显示,网页屏蔽状态栏 打开的网页怎么隐藏浏览器的状态栏
  15. 怎么对本地局域网计算机控制,如何远程控制他人电脑 局域网与互联网控制电脑的方法【详细介绍】...
  16. 2014蓝桥杯本科B组C/C++第四题【史丰收速算】
  17. 从零开始编写SAT求解器(一)
  18. NX torchvision巨坑
  19. 瑞熙贝通大型仪器共享预约平台建设方案
  20. 计算机二级vb弹出式菜单,等考二级VB:用VB、VFP设计右键弹出式菜单

热门文章

  1. 如何更好的与人沟通?[图]
  2. 两个ListBox的相互操作
  3. shell中变量的取值与赋值
  4. C++基础学习笔记001
  5. React Native开发之npm start加速
  6. git版本号管理工具的上手
  7. PHP内核探索:Zend引擎
  8. MPLS自身的优点所带来的网络便捷—Vecloud微云
  9. Zipline Development Guidelines
  10. Python基础(6)_函数