当数据维数过大的时候,会有很多问题。比如说
比如说有下列二维数据,每个“叉”代表一个数据点。PCA会分析出数据主要分布的轴和次要分布的轴。
下图的U1就是PCA的principle component。U2是次要component。在PCA中,他们的关系总是orthogonal的。U1是通过最大化数据的variance来找到的。而U2在这里可以称为noise。
这是一个二维的数据,如果你想用PCA降低维数,那么PCA的结果会忽略U2轴。以U1作为新的basis。所有数据变成单纯的一个U1方向的值。由此把一个二维数据转化为了一维数据。
得到新的一维数据的方法也很简单:就是拿原有数据的矩阵乘以向量U1。原始数据格式必须是m行2列。这里m对应的是每一个observation,2列对应的是数据的维数。
在PCA中,改变后的数据我们称为scores,u1,u2我们称为loadings。
Implementation:
Matlab自带的PCA处理function叫做princomp(),如果想要自己implement的话可以按照如下的方法:
1. 预处理:
Zero Mean Out:
首先要把每一维的数据都减去各自的平均数。
当数据的各个维数单位不统一的时候,才需要这一步。如果是相同的单位,可以省略这个步骤。
把每一维数据都除以各自的variance。
2.预处理之后,求出数据的covariance matrix(correlation matrix单位不统一的话)
不熟悉如何求covariance的话,可以上网查或者去找一些统计学的资料看一下。在matlab中,可以通过cov()求出covariance matrix。
3. 求出covariance的eigenvector和eigenvalue
每个eigenvalue都对应一组eigenvector。最大的eigenvalue对应的eigenvector就是PCA的principle component。
假设有一个N维的数据,你想要降低到k维。那么就取top k eigenvalue对应的eigenvector就可以了。
在matlab中,可以通过eig()求出eigenvalue和eigenvector。
当数据量和数据维数非常大的时候,用covariance的方法解PCA会变得非常inefficient。
Singular Value Decomposition(SVD):
线性代数中的Singular Value Decomposition(SVD)为解决这个问题提供了非常好的方法。
SVD说,任意矩阵X都可以被分解成:
我们简单地推导一下:可是这有什么意义呢?
回想一下:
如果有一个m行n列的数据,m是observation,n是feature维数。
还有另一种方法可以计算Principle component,叫做Power Iteration。
这种方法有点像牛顿迭代。是一个不停的循环,更新,直到收敛的方法。
假设你现在有一个m行n列的数据,m是observation,n是feature的维数。
首先normalize them。
求出covariance matrix。假设它叫做A
接着需要猜一个初始的eigenvector的值,normalize it。任何值都可以,但是要n行一列。假设它叫做b0.
之后开始循环:
下面贴上我自己写的一个简陋的Power iteration代码。经测试和matlab自带princomp()得到相同结果:
联系客服