水熊虫
水熊虫
不认命,就拼命!
263文章 52分类

机器学习之PCA算法

数据降维

数据对于算法工程师来说可以说是无限复杂的,而这个复杂我们是不可能预估的,聪明而又懒惰嗯数据科学家发明一种方法叫做降维,不管你有多少维,维就要处理20维,所以这就是数据降维的由来,本文会介绍一种非常普通且好使的数据降维的方法--PCA

数据降维是机器学习下比较热门的一个话题,在数据挖掘的领域我们尝试使用一组特征来描述我们的主体,但是如何具体的描述一个主体呢?需要多少维度呢? 例如我们想要描述一个人,除了年龄、性别是不是还有血压温度、好人坏人、脾气好坏等等。简直就是枚举不完,如果我们无脑的罗列,那这些特征是不是就太多了,用1w维描述一个人吗? 好吧,这个我们也不知道,但是有一点我们是知道的,就是太多了,这里可能对于某些人来说没有什么用,例如对于医疗大数据来说,他们更关心血压、体温。对于性格、交际可能不需要特别了解。那怎么办呢?这个就是本文要说的,我们要降低维度,保留下来我们更加关心的维度,丢掉一些次要信息。当然如果你是一个专家,你可以通过特征选择来解决这个问题,如果不行,那么就需要本文的方法了。

PCA

中文名字叫做主成分分析算法,非常直白,就是把主要的成分提取出来,然后去除相关性[^1]的方法。它通过线性变换将原始特征映射到其他维度中。降低维度说明的是表示用一个近似的向量表示元素数据。

$$y=Wx$$

从上面的公式中能看出,$x$是原始数据,$y$是投影以后的向量,那么$W$如何来求呢?我们称这个$W$为投影矩阵,如果$W$知道了,那么我们这个算法就讲完了,嗯 太好了了,思路非常清晰。我们先来无脑的思考一个问题,我们有$n$个$d$维向量$x$,我们想把$d$组向量压缩一个向量$x_0$,如何做比较合适呢?如果使用均方误差作为衡量标准。

$$ L(x0) = \sum_{i=0}^{n} ||x-x_0||^2 $$

显然,这个问题的最优解是不是当$x$每组取均值就可以让上面这个损失最小。当然本着科学的理念我们还是要证明的。就是求梯度为0的状态被。

$$\nabla L(x_0)=2(x_0-x)=0$$

求解上面的方程,可以得出上面提到的结论。

当然这个太过于简单,我会表示成如下形式:

$$ m=\frac{1}{n} \sum_{i=1}^{n} x_i $$

$$x=m+a_ie$$

$a_i$是标量,$e$是单位向量。这个时候的误差函数为:

$$ L(a,e)=\sum_{i=1}^{n} ||m+a_ie-x_i||^2 $$

求损失函数的最小值,对$a_i$求导,另整个偏导数为0

$$2e^T(m+a_ie-x_i)=0$$

$$a_ie^Te=e^T(x_i-m)$$

因为$e^Te=1$,所以

$$a_i=e^T(x_i-m)$$


上面这个公式表达的含义是,样本均值和样本的方差的差对向量$e^T$做投影。现在就会有另一个问题$e^T$如何来确认?下面我们来引入一个散布矩阵[^2].我们稍后会用到。

$$ S=\sum_{i=1}^{n}(x_i-m)(x_i-m)^T $$

不难发现,散布矩阵实际上是协方差矩阵的n倍。协方差矩阵定义如下

$$ \Sigma=\frac{1}{n} \sum_{i=1}^{n}(x_i-m)(x_i-m)^T $$


好的,我们言归正传,将上面求的的$a_i$带入下面的目标函数,可以得到关于$e$的变量。

$$ L(e)=\sum_{i=1}^{n} (a_ie+m-x_i)^T(a_ie+m-x_i) $$

$$ =-e^TSe+\sum_{i=1}^{n}(m-x_i)^T(m-x_i) $$

这里的S就是上面提到的散布矩阵哦。其中过程大家可以动手练练。

上面这公式我们发现,后半部分是和$e$无关的,也就是我们可以当成常数了,那么我们将关注点放到$e$上,$e$是单位向量,隐含条件就是$e^Te=1$,那么上面这个公式就能引入拉格朗日函数变成一个优化问题。

$$ L(e,\lambda)=-e^TSe+\lambda(e^Te-1) $$

求导并且等于0就能得到。

$$\begin{gathered}-2Se+2\lambda e=0 \\ Se=\lambda e\end{gathered}$$

很明显,等式两边都有$e$,且结果是相等的,那么$\lambda$是散布矩阵$S$的特征值。$e$是特征向量,再一次转化为矩阵的特征值和特征向量的问题。矩阵$S$是半正定的[散布矩阵],因此一定是可以对角化的,并且所有特征值非负,对于任意的非0向量$x$,有

$$ x^TSx=x^T(\sum_{i=1}^{n}(m-x_i)^T(m-x_i))x $$

$$ = \sum_{i=1}^{n}(x^T(m-x_i)^T)(x^T(m-x_i))>=0 $$

我们这里需要最大化$$e^Te$$,上面已经提到过了,将$Se=\lambda e$两边同时乘以一个$e^T$,会有如下公式

$$ e^TSe=\lambda ee^T=\lambda $$

当$\lambda$为散布矩阵的最大特征值的时候,$$e^TSe$$具有最大值,目标函数具有最小值。而$\lambda$是散布矩阵的特征值,也就是我们仅仅需要对散布矩阵进行特征值和特征向量分解,然后按照我们的需求和从大到小的顺序求我们想要的维度即可。

算法流程

计算样本集合的均值向量,将所有的向量减去均值向量,这个操作成为白化
计算样本协方差矩阵
对协方差矩阵进行特征值分解,得到所有的特征值和特征向量
将特征值从大到小排序,保留最大的一部分特征值对应的特征向量,以他们为行,形成投影矩阵。

降维过程

将样本减去均值向量  
左乘投影矩阵,得到降维后的矩阵

数据重构

数据重构根据投影后的数据重构原始向量,于向量投影的作用相反
输入向量左乘以投影矩阵
加上均值向量就可以得到重构后的矩阵。

代码实例

行万里路,不如来段代码,咱们看看代码是如何实现这一个过程的,当然咱们生成环境中是有很多开源的控价来实现这一个过程的。

```python

coding=utf-8

import numpy as np data = np.array([[2.5,2.4], [0.5, 0.7], [2.2, 2.9], [1.9, 2.2], [3.1, 3.0], [2.3, 2.7], [2, 1.6], [1, 1.1], [1.5, 1.6], [1.1, 0.9]])

print "原始数据:" print data def zeroMean(dataMat): # 白化 meanVal = np.mean(dataMat, axis=0) newData = dataMat - meanVal return newData, meanVal

newData, meanVal = zeroMean(data) covMat = np.cov(data, rowvar=0)

提取特征值和特征向量

eigVals, eigVects = np.linalg.eig(np.mat(covMat))

print "特征值:" print eigVals print "特征向量:" print eigVects

降低维度

k = 1 # 期望降低维度 eigValIndice = np.argsort(eigVals) # 从小到大排序 n_eigValIndice = eigValIndice[-1:-(k+1):-1] # 取值最大的k个下标 n_eigVect = eigVects[:, n_eigValIndice] # 取对应的k个特征向量 lowDataMat = newData*n_eigVect print "低维度空间:" print lowDataMat print "重构数据:" reconMat = (lowDataMat * n_eigVect.T) + meanVal print reconMat

为了便于观看和学习,输出数据咱们就放到这里了。

python 原始数据: [[2.5 2.4] [0.5 0.7] [2.2 2.9] [1.9 2.2] [3.1 3. ] [2.3 2.7] [2. 1.6] [1. 1.1] [1.5 1.6] [1.1 0.9]] 特征值: [0.0490834 1.28402771] 特征向量: [[-0.73517866 -0.6778734 ] [ 0.6778734 -0.73517866]] 低维度空间: [[-0.82797019] [ 1.77758033] [-0.99219749] [-0.27421042] [-1.67580142] [-0.9129491 ] [ 0.09910944] [ 1.14457216] [ 0.43804614] [ 1.22382056]] 重构数据: [[2.37125896 2.51870601] [0.60502558 0.60316089] [2.48258429 2.63944242] [1.99587995 2.11159364] [2.9459812 3.14201343] [2.42886391 2.58118069] [1.74281635 1.83713686] [1.03412498 1.06853498] [1.51306018 1.58795783] [0.9804046 1.01027325]]

进一步

根据上面对PCA的数学原理的解释,我们可以了解到一些PCA的能力和限制。PCA本质上是将方差最大的方向作为主要特征,并且在各个正交方向上将数据“离相关”,也就是让它们在不同正交方向上没有相关性。如果处理不相关特征,可以了解一些关于流行学习的知识。

PCA也存在一些限制,例如它可以很好的解除线性相关,但是对于高阶相关性就没有办法了

备注

1: 去除相关性是什么鬼?其实对于我们的大多数的机器学习算法来讲,都是假设我们的特征是独立的,不希望有些特征是相互影响的,所以主成分分析算法,还有一个左右就是将相关性的特征进行剥离,抽取最重要的特征。 2: 在统计学与概率论中,散布矩阵是一个矩阵,其每个元素是各个向量元素之间的协方差。是从标量随机变量到高维度随机向量的自然推广。

Your browser is out-of-date!

Update your browser to view this website correctly. Update my browser now

×