参考文献1:PCA的数学原理(讲得极好)
参考文献2:《机器学习导论》
题外话:
上次,参加国内业界最牛逼之一的格林深瞳的笔试和面试,没想到竟然都通过了。高兴之余,实际上,还有很长的路要走。
说实话,也是有点幸运,出了很多毕设相关的视觉知识。毕设做得很认真,然后面试时,我自然和面试的那位年轻小伙讲得滔滔不绝。但是第二关是相关的机器学习和深度学习的知识。机器学习我能答上,深度学习就有点措手不及(实际上笔试中相关的深度学习题目我做得不怎么样)。其中一个就是PCA降维。这个东西很早就想看,一直推来推去。现在正式进入主题:
为何降维?
特征选择:从原始输入向量d维中选出信息量最多的k维,并丢弃(d-k)维,记为x(k维)
特征提取:d维向量x投影到k维的x'。这些方法可以是监督的,也可以是非监督的。
虽然,分类方法或回归方法应该能够利用任何必要的特征,而丢弃不想关的特征。然而,有许多原因使得我们对把降维作为一个单独的预处理步骤感兴趣。
1)算法的复杂度依赖于样本维度d和样本数量N
2)如果输入是不必要的,我们就节省了它的开销
3)较简单的模型更为鲁棒
特征选择——子集选择:
d个变量有2d个可能的子集。除非d很小,一般我们不可能对所有的子集进行检验。通常会采用启发式的方式。
有两种启发式的方式:向前选择和向后选择
向前选择(伪代码):
(1)令子集为F,初始化为F={Ø},T={xi|i=1,...,d}。
(2)计算误差j=argmin(i)E(F∪xi)
(3)IF E小于阀值||E不会减少
(i)算法终止:exit()
ELSE
(ii)F=F∪xj,且T=T-xj
(4)goto(2)
问题和改进:
1)搜索复杂度为d+(d-1)+...+(d-k)=O(d2)
2)可能两个特征本身都不好,但是两者合在一起,作用却很大。可能一个解决方法是依次添加m个而不是1个。或者通过回溯并且检查以前添加的哪个特征可以去掉,但搜索速度慢,一个算法是:浮动搜索可以解决一些问题。
向后选择:则是首先包括所有特征,然后每次踢掉一个特征,并且是去掉导致误差最小的那个。
对比:如果我们预料到有许多无用的特征,向前搜索更可取。
缺点:在像人脸识别这样的应用中,特征选择不是降维的好方法,因为个体像素本身并不携带很多识别信息;携带脸部识别信息的是许多像素值的组合。
特征提取——主成分分析:
虽然上图中提到了许多方法,但是这里我只讨论主成分分析:
(1)内积——投影(我似乎悟到了归一化向量的内积能体现向量的相似度,即夹角能体现相似度)
(2)矩阵相乘A×B:看成A×Bi(Bi为B的第i列),于是,看成B矩阵中每一列形成的向量在A(A由创建的一组基一行一行地躺下来形成的)的投影。
(3)如何选择基:选择不同的基可以对同样一组数据给出不同的表示,而且如果基的数量少于向量本身的维数,则可以达到降维的效果。但是我们还没有回答一个最最关键的问题:如何选择基才是最优的。或者说,如果我们有一组N维向量,现在要将其降到K维(K小于N),那么我们应该如何选择K个基才能最大程度保留原有的信息?
(4)那么如何选择这个方向(或者说基)才能尽量保留最多的原始信息呢?一种直观的看法是:希望投影后的投影值尽可能分散。我们希望投影后投影值尽可能分散,而这种分散程度,可以用数学上的方差来表述。
(5)投影到一维的情况:通常,我们事先让投影后的所有值组成的向量的每个分量减去该分量的均值。这样,(4)中所提到的方差,在这步之后,就等于求每个值得平方和。简化了问题。
(6)于是上面的问题被形式化表述为:寻找一组基,使得所有数据变换为这个基上的坐标表示后,方差值最大。
(7)直观上,强调的是,对于二维降到一维,投影之后,我们就得到了一堆标量,然后求其平方和,使之最小化。对于A为m×n的矩阵。即有m个基躺下来。先考虑一个基,每一个数据过来,和它做内积,就变成了一个标量,...,N个数据得到N个标量。计算其离散度,即平法和。同样地,对第二个、第三个,...,第m个基都是如此。最终把所有的离散度(平法和)加起来优化。其中,物理上,m个其代表数据从m个方向投影,希望每个方向投影的离散度结果之和最大化。
(8)在(7)中说的很好了,但问题来了,我们总能够找到一个使方差最大的的基,那我找第二个基的时候,也找相同的基好了,或者稍微偏一点点,那也能接近地找到最大的方差。这么说来,问题就大了,所有基方向都趋于相同。怪怪的!
(9)我们想找到其他的约束条件来解决这个问题。从直观上说,让两个字段尽可能表示更多的原始信息,我们是不希望它们之间存在(线性)相关性的,因为相关性意味着两个字段不是完全独立,必然存在重复表示的信息。
(10)在原坐标基上,显然每个实例向量的各个分量之间的协方差是客观存在,不能改变的了。但是,我们希望投影后,得到的新维度的实例向量的各个分量之间的协方差为0,是它们完全独立,没有冗余的信息量,同样的数据比特,当然没有冗余信息(之间完全独立最好,而不是几个数据或几个变量来表达一个变量的信息)。那么,我们在第一个基方向选定以后(更加最大方差),然后,选择第二个方向和 第一个方向正交(垂直)的方向,同时,我们还想在这个约束条件下方差最大化!同样地,选第三个方向和第一个、第二个方向正交,同时在这个约束条件下,最大化方差,依次类推,直到满足终止条件。
(11)至此,我们得到了降维问题的优化目标:将一组N维向量降为K维(K大于0,小于N),其目标是选择K个单位(模为1)正交基,使得原始数据变换到这组基上后,各字段两两间协方差为0,而字段的方差则尽可能大(在正交的约束下,取最大的K个方差)。
(12)考虑一个问题:
我们看到,最终要达到的目的与实例向量各个分量内方差及实例向量各个分量间协方差有密切关系。因此我们希望能将两者统一表示,仔细观察发现,两者均可以表示为内积的形式,而内积又与矩阵相乘密切相关。于是我们来了灵感:
假设我们只有a和b两个实例向量,那么我们将它们按行组成矩阵X:
其中,AA,BB,AB,BA分别是a分量的方差,b分量的方差,a、b之间的协方差,b、a之间的协方差。
根据矩阵相乘的运算法则,这个结论很容易被推广到一般情况:
设我们有m个n维数据记录,将其按列排成n乘m的矩阵X,设C=frac{1}{m}XX^mathsf{T},则C是一个对称矩阵,其对角线分别个各个分量的方差,而第i行j列和j行i列元素相同,表示i和j两个分量的协方差。
重述一下我们的目标:
(1)希望投影的第一个方向的方差最大。
(2)希望投影的第二个方向与第一个方向正交(协方差为零)且使它的方差最大化。
我们已经可以想象到未来的美好景象:
各个方向投影后:它是一个对角化的方阵,且对角元素从左上角到右下角依次减小。方阵的维数取决于算法终止的时刻。
(13)根据上述推导,我们发现要达到优化目前,等价于将协方差矩阵对角化:即除对角线外的其它元素化为0,并且在对角线上将元素按大小从上到下排列,这样我们就达到了优化目的。
(14)现在事情很明白了!我们要找的P不是别的,而是能让原始协方差矩阵对角化的P。换句话说,优化目标变成了寻找一个矩阵P,满足PCP^mathsf{T}是一个对角矩阵,并且对角元素按从大到小依次排列,那么P的前K行就是要寻找的基,用P的前K行组成的矩阵乘以X就使得X从N维降到了K维并满足上述优化条件。
(15)现在所有焦点都聚焦在了协方差矩阵对角化问题上,有时,我们真应该感谢数学家的先行,因为矩阵对角化在线性代数领域已经属于被玩烂了的东西,所以这在数学上根本不是问题。
(16)
由上文知道,协方差矩阵C是一个是对称矩阵,在线性代数上,实对称矩阵有一系列非常好的性质:
1)实对称矩阵不同特征值对应的特征向量必然正交。
2)设特征向量lambda重数为r,则必然存在r个线性无关的特征向量对应于lambda,因此可以将这r个特征向量单位正交化。
由上面两条可知,一个n行n列的实对称矩阵一定可以找到n个单位正交特征向量,设这n个特征向量为e_1,e_2,cdots,e_n,我们将其按列组成矩阵:
E=egin{pmatrix} e_1 & e_2 & cdots & e_n end{pmatrix}
则对协方差矩阵C有如下结论:
E^mathsf{T}CE=Lambda=egin{pmatrix} lambda_1 & & & \ & lambda_2 & & \ & & ddots & \ & & & lambda_n end{pmatrix}
其中Lambda为对角矩阵,其对角元素为各特征向量对应的特征值(可能有重复)。
以上结论不再给出严格的数学证明,对证明感兴趣的朋友可以参考线性代数书籍关于“实对称矩阵对角化”的内容。
到这里,我们发现我们已经找到了需要的矩阵P:
P=E^mathsf{T}
P是协方差矩阵的特征向量单位化后按行排列出的矩阵,其中每一行都是C的一个特征向量。如果设P按照Lambda中特征值的从大到小,将特征向量从上到下排列,则用P的前K行组成的矩阵乘以原始数据矩阵X,就得到了我们需要的降维后的数据矩阵Y。
(17)
PCA算法
总结一下PCA的算法步骤:
设有m条n维数据。
1)将原始数据按列组成n行m列矩阵X
2)将X的每一行(代表一个属性字段)进行零均值化,即减去这一行的均值
3)求出协方差矩阵C=frac{1}{m}XX^mathsf{T}
4)求出协方差矩阵的特征值及对应的特征向量
5)将特征向量按对应特征值大小从上到下按行排列成矩阵,取前k行组成矩阵P
6)Y=PX即为降维到k维后的数据
(18)例子略(详见参考文献1)