PCA算法(主成分分析)

写在前面

Principle Component Analysis 顾名思义,是通过分析向量空间的主成分,将主成分提取出来,不重要的成分略去,从而达到降维压缩信息的目的。

那什么才是主成分呢?大家应该知道,一个空间会有自己的一组基向量,空间中的任何一个向量都可以通过基向量的组合来表示。

举个栗子,假如我们有一组2维的点,那么我们可以找到2个基向量,让这一组点对着这2个基向量进行投影。每个基向量上,投影后的点越分散,这个基向量就越重要。也就是主成分。不明白的看下图。(原谅我的灵魂画作)

这里写图片描述

红色的点就是已有的一组2维点,黄色和蓝色的线代表两个基向量的方向。如果我们要把红色的点从2维降到1维,向哪个方向投影才能保存更多的信息呢?直观上看,当然是黄向量比较好,红点在黄线上的投影很分散,而在蓝线上的投影很多会重叠在一起。黄向量就是比蓝向量更主要的成分。

好了,我们现在知道什么是主成分了,那怎么才能把它提取出来呢?一般是通过对红点各维的协方差矩阵进行特征分解,选取最大的几个特征值对应的特征向量,组成低维空间的一组基向量。再将原始的红点投影到这组低维基向量上,就得到了红点降维后的坐标。这中间涉及到一些数学的计算和解释,就放在下面了。

投影

向量的内积相当于投影,

 A * B = |A||B|cos(a)

|B|=1时,

 A * B= |A|cos(a)

此时,A和B的内积相当于A向B方向投影的长度。

另外,当新基的原点与原基的原点不同时,要先进行变换使原点重合。

讨论二维空间基变换

在我们常用的笛卡尔坐标系中,一点(x,y)可以分解为

 x = r * cos(θ)   y = r * sin(θ)

相当于把向量(x,y)投影到两个基向量上,

 (1,0) 和 (0,1)

x和y相当于投影后的长度。

一个向量的准确描述需要给出一组基,以及向量在各个基方向上的投影长度。

注意:不管变换什么样的基向量,向量相对于原点的位置是不变的。

例:将基本基上的坐标(3,2)变换为基(1/√2,1/√2)、(-1/√2,(1/√2))的坐标。
(注意,新基的坐标是在基本基上确定的)

12121212(32)=5212

(52,12)
即为变换后的坐标。

多维空间基变换

M个N维向量(组成矩阵A),将其变到R个N维基(组成矩阵B)表示的新空间中

矩阵AB中第m列为A中第m列的变换结果。

这里写图片描述

两个矩阵相乘的意义是将右边矩阵中的每一列列向量变换到左边矩阵中每一行行向量为基所表示的空间中去。

方差

为实现降维,就要使降维后的结果尽量的分散(重叠太多就不能很好地复原回去),也就是降维后的方差尽量大。

协方差

两个字段的协方差表示其相关性,

这里写图片描述

  • 如果结果为正值,则说明两者是正相关的。
  • 如果结果为负值,则说明两者是负相关的。
  • 如果为0,也是就是统计上说的“相互独立”。

理解协方差矩阵的关键就在于牢记它计算的是不同维度之间的协方差,而不是不同样本之间,拿到一个样本矩阵,我们最先要明确的就是一行是一个样本还是一个维度。

a,b两个字段组成X,
(相当于m个点的x和y值)

这里写图片描述

对角线上的为每个字段各自的方差,其它元素为协方差。

我们要使最后各个方向(字段)的差距大,如果各个方向相似,这个投影是没有太大作用的。也就是说协方差尽可能的为0。

PCA计算

X:原始矩阵
C : X对应的协方差矩阵
P : 新基的矩阵
Y = PX
Y : X对P做基变换后的矩阵
D : Y的协方差矩阵

这里写图片描述

只要找到一组基的矩阵P,使得D为对角矩阵(Y的协方差为0),并且对角元素按从大到小依次排列,那么P的前K行就是要寻找的基(从N维降到K维)。

又因为C是对称矩阵,满足,

这里写图片描述
(E为正交矩阵)

可得,

P=ET

所以,我们可以通过对X的协方差矩阵C的特征分解,来得到E。取E中特征值最大的几个特征值对应的基向量组成P,从而得到降维后的矩阵Y。

在网上看到了一个PCA算法步骤,觉得挺清楚就粘贴过来了。

这里写图片描述
注:k的选择。一般选择占所有能量99%的特征值。

程序实现

自己写了一个简单的python函数实现PCA,具体的解释可以看函数前面的注释~

"""
Author: totodum
Program: Linear_PCA.py
Description: Linear Principle Component Analysis
"""
from numpy import *
from numpy.linalg import *


'''
PCA takes an array of points, each row is a single point. and reduce the dimension
    of the points to k-D.
    return points of k-D.
'''


def pca(x, k):
    m = x.shape[0]
    c = dot(transpose(x), x) / m  # coefficient
    [u, s, v] = svd(c)
    p = u[:, 0:k]
    y = dot(x, p)
    return y

这个是做作业的效果图(3维降到2维)

三维:
这里写图片描述

二维:
这里写图片描述

参考:http://www.360doc.com/content/13/1124/02/9482_331688889.shtml

展开阅读全文

没有更多推荐了,返回首页