主元分析和奇异值分解

主元分析和奇异值分解

主元分析或者主成分分析,即PCA(Principal Component Analysis)和奇异值分解,即SVD(Singular Value Decomposition)都是常用的对数据进行预处理进行降维的方法,通常我们认为样本的一个特征为一个维度,即特征向量中的维度,若样本的特征非常非常多,那么对于各种算法来说算起来都是很耗时耗内存的,这时就应该降维,同时要保持大部分原有的信息不丢失。

PCA

主成分分析是一种很常见的降维工具,其目标是在样本数据空间中找到新的坐标轴,即新的正交基,使得原有样本能够映射到新的坐标轴上,我们通常认为方差大的数据才是有用的数据,方差小的数据为噪声数据,则在新的空间选取方差较大的坐标轴,将方差小的坐标轴舍弃掉,这就实现了降维

例如数据有A和B两个特征,若A,B的变化是一样的,则完全可以舍弃掉其中一个。

步骤:输入样本集 D = D= D={ x 1 , x 2 , ⋯   , x m x_1,x_2,\cdots,x_m x1,x2,,xm},每个样本有 d d d个特征,输出为维数为 d ^ , d ^ < d \hat{d},\hat{d}<d d^,d^<d的样本

  1. 对所有样本进行中心化处理,即使得样本的均值为0。 x i = x i − 1 m ∑ i = 1 m x i x_i=x_i-\frac{1}{m}\sum_{i=1}^mx_i xi=xim1i=1mxi
  2. 计算样本的协方差矩阵 R R R,其中 r i j = C o v ( x i , x j ) r_{ij}=Cov(x_i,x_j) rij=Cov(xi,xj)
  3. 求出协方差矩阵 R R R的所有特征值和特征向量
  4. 对特征值进行降序排序,取前 d ^ \hat{d} d^个特征值 λ 1 , λ 2 , ⋯   , λ d ^ \lambda_1,\lambda_2,\cdots,\lambda_{\hat{d}} λ1,λ2,,λd^及其对应的特征向量 w 1 , w 2 , ⋯   , w d ^ w_1,w_2,\cdots,w_{\hat{d}} w1,w2,,wd^,这些特征向量便构成映射后的空间的坐标轴
  5. 对原有样本进行映射 D ^ = D ∗ W \hat{D}=D*W D^=DW D D D m ∗ d m*d md矩阵, W W W d ∗ d ^ d*\hat{d} dd^矩阵
  6. 特征向量 w i w_i wi即映射后的坐标轴 i ⃗ \vec{i} i ,其对于原有数据的方差的贡献率为 λ i ∑ j = 1 m λ j \frac{\lambda_i}{\sum_{j=1}^m \lambda_j} j=1mλjλi

最后的输出维数 d ^ \hat{d} d^可以根据数据的不同而不同,还可以设置一个阈值,例如 t = 90 t=90 t=90%,取使下式成立的最小的 d ^ \hat{d} d^
∑ i = 1 d ^ λ i ∑ i = 1 d λ i ≥ t \frac{\sum_{i=1}^{\hat{d}}\lambda_i}{\sum_{i=1}^d\lambda_i}\ge t i=1dλii=1d^λit
原理推导:为什么是协方差的特征向量就是新空间的坐标轴呢?特征值越大代表什么?

首先我们的目标是找到新的正交基或者新的坐标轴来映射,并且在该正交基映射后方差最大,即映射后各样本之间的距离足够远。

例如:这个二维数据点映射在蓝色直线上,以该蓝色直线为新的坐标轴 U 1 U_1 U1,这样就可以由2维降到1维,且信息能够最大程度保留。若映射到红色这条线,虽然也是降维,但是数据之间的关系丢失了,信息也丢失了。
在这里插入图片描述
所以对于上面的二维数据,我们的目标就是找到一个方向基,使数据映射后的方差有最大值。当然这个只是二维降到一维,若三维降到二维,则还要找到新的方向基,此时就不能仅仅是再找映射后方差最大了,因为方差最大只有一条,那我想方差第二大呢?这也不行,因为这可能只与第一个方向基差一点点,几乎重合,所以我们要想第二个方向基于第一个方向基没有任何相关性,即这两个方向基的协方差为0,形象点就是要正交,加上这个约束条件我们再找方差最大的坐标轴。

  • 协方差的定义是 E ( ( x − E ( x ) ( y − E ( y ) ) ) E((x-E(x)(y-E(y))) E((xE(x)(yE(y)))

补:这里要补充一下线性代数的理解,矩阵 A A A,向量 x x x,那么 A x = y Ax=y Ax=y,相当于 x x x A A A的作用下进行一次变换,更深的理解是以 A A A行向量为新的基,即为新的坐标轴,在这个新空间里, x x x就表示成 y y y,这就好理解主成分分析里的映射关系了。

这样我们要找的新的空间来映射,这个新的空间就可以表示为一个矩阵 P P P,我们不妨将 P T P^T PT作为新空间的映射矩阵,为什么要转置呢?因为 P T P^T PT的行向量为新的正交基,则 P P P的列向量为新的正交基,而我们最后求出来的 P P P正是由特征向量组成,特征向量就是新的基。

假设数据集有m个样本,d个特征,一般我们喜欢的样本矩阵是 X X X是m*d的,但在这里我们需要 X T X^T XT,即d*m的,这样矩阵 X T X^T XT的每一列是一个样本,这样就将样本能通过映射矩阵进行映射,且有下列变化:
P T : d ^ ∗ d ( 每 一 行 为 一 个 坐 标 轴 ( 基 ) , 有 d ^ 行 , 则 映 射 后 维 度 为 d ^ ) X T : d ∗ m ( 每 一 列 为 一 个 样 本 , 每 个 样 本 有 d 个 特 征 ) 则 P T X T 将 数 据 集 进 行 映 射 , 大 小 为 d ^ ∗ m 为 了 符 合 习 惯 , 我 们 转 置 一 下 大 小 为 m ∗ d ^ , 则 样 本 的 特 征 减 少 d − d ^ 个 X ^ = ( P T X T ) T = X P , X 大 小 为 m ∗ d ^ P^T:\hat{d}*d(每一行为一个坐标轴(基),有\hat{d}行,则映射后维度为\hat{d})\\ X^T:d*m(每一列为一个样本,每个样本有d个特征)\\ 则P^TX^T将数据集进行映射,大小为\hat{d}*m\\ 为了符合习惯,我们转置一下大小为m*\hat{d},则样本的特征减少d-\hat{d}个\\ \hat{X}=(P^TX^T)^T=XP,X大小为m*\hat{d} PT:d^d(),d^d^XT:dmdPTXTd^mmd^dd^X^=(PTXT)T=XP,Xmd^
那么 X ^ \hat{X} X^就是我们所要求的降维后的数据集,它应该符合上述的要求,即每个数据的方差最大,且数据间没有相关性,即协方差为0,这怎么做到呢?我们要根据此求出 P P P出来。

既涉及数据内方差又涉及数据间协方差,协方差矩阵很完美的能够表示出来了。我们的新数据集 X ^ \hat{X} X^每一列就是在某一个坐标轴映射上的值,不妨令 X ^ = [ x ^ 1 , x ^ 2 , ⋯   , x ^ d ^ ] \hat{X}=[\hat{x}_1,\hat{x}_2,\cdots,\hat{x}_{\hat{d}}] X^=[x^1,x^2,,x^d^] x ^ i \hat{x}_i x^i为一个列向量,表示所有样本在坐标轴 U i U_i Ui上的映射值,则 X ^ \hat{X} X^的协方差矩阵为 D , d i j D,d_{ij} D,dij C o v ( x ^ i , x ^ j ) Cov(\hat{x}_i,\hat{x}_j) Cov(x^i,x^j),可以看出 D D D是一个对称矩阵,大小为 d ^ ∗ d ^ \hat{d}*\hat{d} d^d^,对称轴是方差。

  • 上述要求等价于这个协方差矩阵 D D D对角元素最大,则非对角元素值为0。(条件一)

我们回到开始,PCA步骤一做的是数据的中心化,且这一步是必须的,这有什么用呢?就是为了方便求出协方差矩阵!中心化后的数据均值为0,那么无论是求方差还是求协方差,数据都要减去均值,那么正好减去0就相当于不用动了!

假设矩阵为
[ a 1 b 1 a 2 b 2 ⋯ ⋯ a d b d ] \begin{bmatrix} a_1 & b_1\\ a_2 & b_2\\ \cdots & \cdots \\ a_d & b_d \\ \end{bmatrix} a1a2adb1b2bd
对应我们的样本集 X X X,为m*d,即每一行代表一个样本,不同字母代表不同特征,对上面矩阵第一列记为 A A A,第二列记为 B B B,为什么要记列呢,因为我们协方差矩阵算的是列与列之间的协方差,即不同坐标轴之间的协方差。并且该矩阵已经中心化处理,即每一列的均值为0.

则上述矩阵的协方差矩阵为
[ ∑ i = 1 d a i 2 ∑ i = 1 d a i ∗ b i ∑ i = 1 d a i ∗ b i ∑ i = 1 d b i 2 ] \begin{bmatrix} \sum_{i=1}^da_i^2 &\sum_{i=1}^da_i*b_i\\ \sum_{i=1}^da_i*b_i & \sum_{i=1}^db_i^2\\ \end{bmatrix} [i=1dai2i=1daibii=1daibii=1dbi2]
这个矩阵可以看到 A A A的方差为 ∑ i = 1 d a i 2 \sum_{i=1}^d a_i^2 i=1dai2 B B B的方差为 ∑ i = 1 d b i 2 \sum_{i=1}^db_i^2 i=1dbi2 A A A B B B的协方差为 ∑ i = 1 d a i ∗ b i \sum_{i=1}^da_i*b_i i=1daibi.

因为中心化之后均值为0那么方差和协方差就是元素值相乘.

并且进一步有公式若矩阵 X X X的大小为m*d,则 1 d X T X \frac{1}{d}X^TX d1XTX就是 X X X的协方差矩阵(要满足数据中心化)

我们回到条件一,记原有数据集为 X : m ∗ d X:m*d X:md,降维后数据集 X ^ : m ∗ d ^ \hat{X}:m*\hat{d} X^:md^,原有数据集协方差矩阵为 R : d ∗ d R:d*d R:dd,降维后数据集协方差矩阵为 D : d ^ ∗ d ^ D:\hat{d}*\hat{d} D:d^d^。降维变换矩阵为 P : d ∗ d ^ P:d*\hat{d} P:dd^有以下变换:
D = 1 d ^ X ^ T X ^ = 1 d ^ ( X P ) T ( X P ) = 1 d ^ P T X T X P = P T 1 d ^ X T X P = P T R P D=\frac{1}{\hat{d}}\hat{X}^T\hat{X}\\ =\frac{1}{\hat{d}}(XP)^T(XP)\\ =\frac{1}{\hat{d}}P^TX^TXP\\ =P^T\frac{1}{\hat{d}}X^TXP\\ =P^TRP D=d^1X^TX^=d^1(XP)T(XP)=d^1PTXTXP=PTd^1XTXP=PTRP
这里发现要想满足条件一,即协方差矩阵 D D D对角元素最大,则非对角元素值为0,不就是要矩阵 R R R做特征值分解吗?且协方差矩阵 D D D对角线元素就是矩阵 R R R的特征值,我们只要去最大的 d ^ \hat{d} d^个特征值,就可以构成 D D D,且降维变换矩阵 P P P,就是那 d ^ \hat{d} d^个最大的特征值对于的特征向量呀!

这里还要补充的是 R R R是个对称矩阵,大小为d*d,那么肯定有d个不相关的特征向量,正好上述能够成立!

自此PCA就推导出来了,我们有原有数据集的协方差矩阵的特征向量作为变换矩阵。

并且特征值越大,则代表映射后的数据方差越大,效果越好,我们以根据特征值大小来比较贡献,当贡献率到达一定阈值时,新数据能够几乎代表原有数据且维度减少。下图则表示20个特征的原有样本的协方差矩阵可以有20个特征向量和特征值,我们只需取前6大的特征值,就能大幅度将原有样本的方差表示出来,将20降维到6。
在这里插入图片描述
代码实现

def loadDataSet(filename):
    dataSet = []
    fr = open(filename)
    for line in fr.readlines():
        curLine = line.strip().split('\t')
        fltLine = map(float,curLine)
        dataSet.append(list(fltLine))
    return mat(dataSet)
def pca(dataMat,topNfeat=9999999):
    meanVals = mean(dataMat,axis=0) #对列取均值
    meanRemoved = dataMat-meanVals  #数据中心化
    print(shape(meanRemoved))
    covMat = cov(meanRemoved,rowvar=0)  #协方差矩阵,rowvar=0指以一行为一个样本
    print(shape(covMat))
    eigVals,eigVects = linalg.eig(mat(covMat)) #特征值和特征向量
    eigValInd = argsort(eigVals) #argsort是排序后返回index,升序
    eigValInd = eigValInd[:-(topNfeat+1):-1] #从最后一列到topNfeat+1列返回
    redEigVects = eigVects[:,eigValInd] #取出相应的特征向量
    lowDDataMat = meanRemoved*redEigVects #将原数据进行映射
    reconMat = (lowDDataMat*redEigVects.T) + meanVals 
    return lowDDataMat,reconMat

奇异值分解下一篇再讲

评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值