PCA降维算法的Python实现
摘要
PCA算法本质实际上是n维数据向量空间的基变换,再将数据向量投影在变化之后的基之上,从而达到降维的目的,为了使n维数据向量在降维之后仍能尽可能保持原有的信息量,这就类似于有损压缩的概念(有损压缩是指使用压缩后的数据进行重构,重构后的数据与原来的数据有所不同,但不影响人对原始资料表达的信息造成误解)。所以基的选择自然显得十分重要。
信息熵
PCA降维的目的首先就是要尽可能保持其原有的信息量。那么信息的度量或者量化标准则成了一个关键问题。
所谓信息量是指从N个相等可能事件中选出一个事件所需要的信息度量或含量,也就是在辩识N个事件中特定的一个事件的过程中所需要提问"是或否"的最少次数. —《百度百科》
信息量与事件的不确定性有关
如果一个事件,不论在什么情况下,发生的结果都不会发生变化,那我们就认为它所包含的信息量为0。比如说一个程序,在代码不变的情况下,只要输入固定其结果必然一定,不论我们运行多少次都是同样的结果,我们从中所能获取的信息几乎为0,因为这件事对我们来说已经是非常确定了的。我们说科学就是探索未知,因为未知包含了无限的可能,包含了无限的信息。
香农给出了信息度量的定义:信息是用不确定性的量度定义的.一个消息的可能性愈小,其信息愈多;而消息的可能性愈大,则其信息愈少.事件出现的概率小,不确定性越多,信息量就大,反之则少。
换句话说,信息的度量是与概率相关的。
熵
依据Boltzmann's H-theorem,香农把随机变量X的熵值 Η定义如下,其值域为{x1, ..., *x**n*}:
其中,P为X的概率质量函数(probability mass function),E为期望函数,而I(X)是X的信息量。I(X)本身是个随机变数。
当取自有限的样本时,熵的公式可以表示为:
在这里b是对数所使用的底,通常是2,自然常数e,或是10。当b = 2,熵的单位是bit;当b = e,熵的单位是nat;而当b = 10,熵的单位是Hart。
*p**i* = 0时,对于一些i值,对应的被加数0 logb 0的值将会是0,这与极限一致。
还可以定义事件 X 与 Y 分别取 xi 和 yj 时的条件熵为
其中p(xi, yj)为 X = xi 且 Y = yj 时的概率。这个量应当理解为你知道Y的值前提下随机变量 X 的随机性的量。
熵与方差
方差
方差的定义
方差越大数据的波动也就越大,其不确定性自然越大,方差描述不确定度在某些情况下会失效,因为它要求数据均匀分布并且忽略极端事件的发生。熵本就是对信息的不确定度的度量,相比于方差必然更加精确。
基的选择
举个栗子:
假设我们的数据由五条记录组成,将它们表示成矩阵形式:
其中每一列为一条数据记录,而一行为一个字段。为了后续处理方便,我们首先将每个字段内所有值都减去字段均值,其结果是将每个字段都变为均值为0(这样做的道理和好处后面会看到)。
我们看上面的数据,第一个字段均值为2,第二个字段均值为3,所以变换后:
我们可以看下五条数据在平面直角坐标系内的样子:
如果我们必须使用一维来表示这些数据,又希望尽量保留原始的信息,你要如何选择?
直观的说这个问题实际上是要在二维平面中选择一个方向,将所有数据都投影到这个方向所在直线上,用投影值表示原始记录。这是一个实际的二维降到一维的问题。
所以数据样本投影到基后的投影值尽可能分散。也就是使得数据变化到基上的坐标后,方差最大。
优化目标
在多维的情况下,基的维数也是多维,因此投影方向也变成了多维问题,且数据样本的字段存在相关性显然,为了使得样本不同字段之间完全独立(相关性意味着两个字段不是完全独立,必然存在重复表示的信息。),选择的基两两之间必然是正交的。即:
将一组N维向量降为K维(K大于0,小于N),其目标是选择K个单位(模为1)正交基,使得原始数据变换到这组基上后,各字段两两间协方差为0,而字段的方差则尽可能大(在正交的约束下,取最大的K个方差)。
协方差矩阵
我们知道最终优化目标与字段内的方差和字段之间的协方差有关(字段之间独立)
对于矩阵x:
X乘以X的转置,并乘上系数1/m:
我们发现,对角线上的两个元素分别是两个字段的方差,而其它元素是a和b的协方差。要达到优化目前,等价于将协方差矩阵对角化:即除对角线外的其它元素化为0,并且在对角线上将元素按大小从上到下排列,这样我们就达到了优化目的。
设原始数据矩阵X对应的协方差矩阵为C,而P是一组基按行组成的矩阵,设Y=PX,则Y为X对P做基变换后的数据。设Y的协方差矩阵为D,我们推导一下D与C的关系:
变化矩阵P就是原始协方差矩阵对角化的P。
我们知道:协方差矩阵C是一个是对称矩阵,在线性代数上,实对称矩阵有一系列非常好的性质:
1)实对称矩阵不同特征值对应的特征向量必然正交。
2)设特征向量λ重数为r,则必然存在r个线性无关的特征向量对应于λ,因此可以将这r个特征向量单位正交化。
则对协方差矩阵C有如下结论:
对角元素为各特征向量对应的特征值,P对应与E的转置
P是协方差矩阵的特征向量单位化后按行排列出的矩阵,其中每一行都是C的一个特征向量。如果设P按照ΛΛ中特征值的从大到小,将特征向量从上到下排列,则用P的前K行组成的矩阵乘以原始数据矩阵X,就得到了我们需要的降维后的数据矩阵Y。
PCA算法
设有m条n维数据。
1)将原始数据按列组成n行m列矩阵X
2)将X的每一行(代表一个属性字段)进行零均值化,即减去这一行的均值
3)求出协方差矩阵C
4)求出协方差矩阵的特征值及对应的特征向量
5)将特征向量按对应特征值大小从上到下按行排列成矩阵,取前k行组成矩阵P
6)Y=PX即为降维到k维后的数据
结果示例
样本为符合[[-5,5],[5,-5]]的协方差矩阵的数据
Python实现代码
1 | import numpy as np |