在<ml in acthion>最后一部分中,讲到了一些常用的方法,第一个讲到的就是降维(dimensionality-reduction)
书中没有太过深入的将到为什么可以对特征经行降维,于是谷歌上乎找到了一篇引用1000+的文章。
具体链接:http://www.cs.otago.ac.nz/cosc453/student_tutorials/principal_components.pdf
该文较为详细的介绍了一些数学上的东西,能够加深对PCA的了解(后来也没发现太过深入,但是也足够了)。
降维的日常相关:
假如你正在电视机前看一场运动比赛,在屏幕上,你看到的是数百万像素(pixels),由于大脑,你此时已经实时的将这些数据降到一个三维相关数据场景(in real time. You’ve reduced the data from one million dimensions to three),在这次比赛中,你接触到的是百万像素(百万维),但是这个球的三维位置对你而言是最重要的,这就是降维(you’re presented with millions of pixels, but it’s the ball’s three-dimensional position that’s important. This is known as dimensionality reduction)。
可以看到,降维的目的主要有一下几点:
- 让数据集更加容易使用
- 对于多数算法而言,降低计算开销
- 减少噪音
- 让结果更容易理解
针对监督学习和无监督学习,也有多种不同的降维方法,PCA(主成分分析)可以适用于全部类型。
PCA优点:
降低数据复杂度,抓取最重要特征
PCA缺点:
并不是所有数据都需要降维,降维可以导致有用数据丢失。
在PCA中,数据集从原始的坐标系转化到另外一个新的坐标系。新的坐标系是从原来的坐标系中产生,具体方法如下,新坐标系中第一条轴的方向是数据集中方差最多方向,第二条轴的方向是垂直于第一条轴的也就是正交于第一条轴。
如下图所示:
假如有大量2维数据,然后划一条最长的线的话,那么B线是显然最合适的,在PCA中,通过旋转坐标轴,找到最长的第一个坐标(方差产生最大),也就是B(The first axis is rotated to cover the largest variation in the data: line B in figure 13.1. The largest variation is the data telling us what’s most important),选取了第一条轴后,第二条坐标轴选取C线(we choose the next axis,which has the second most variability, provided it’s perpendicular to the first axis)
一个比较直观的例子,比如,有3类数据要经行分类,如图下所示:
通过PCA降维后,得到:
在这幅图里,只有一条坐标轴,其他的轴对分类来说贡献不大,可以看作是噪音,可以不考虑。
从二维降到一维的话,看着效果不明显,但是从更高维降到一个低维的话,就有意义了。
这是从一个比较感性直观的角度来理解降维,通常来说,找到这些重要的坐标轴可以通过协方差矩阵和特征值分析来获取(We can get these values by taking the covariance matrix of the dataset and doing eigenvalue analysis on the covariance matrix)。
只要我们协方差矩阵中,排名靠前的前N个特征向量代表了前N个重要的特征。然后将原始数据与前N个特征向量做乘法就可以转换得到新的空间新特征数据(We can then multiply the data by the top N eigenvectors to transform our data into the new space.)。
利用python的一些库,可以很容易做到:
- 减去对应维度算数平均数
- 计算协方差矩阵
- 找到协方差矩阵的特征值
- 对特征值排序
- 按照需要,获取前N个特征向量
- 原始数据与特征向量做计算
<span style="font-size:18px;">from numpy import *
def pca(dataMat, topNfeat=9999999):
meanVals = mean(dataMat, axis=0)
meanRemoved = dataMat - meanVals
covMat = cov(meanRemoved, rowvar=0)
eigVals,eigVects = linalg.eig(mat(covMat))
eigValInd = argsort(eigVals)
eigValInd = eigValInd[:-(topNfeat+1):-1]
redEigVects = eigVects[:,eigValInd]
lowDDataMat = meanRemoved * redEigVects
reconMat = (lowDDataMat * redEigVects.T) + meanVals
return lowDDataMat, reconMat</span>
-------------------------------------------------------分割线-------------------------------------------------------
PCA中涉及到的一些数学知识
PCA中比较关键的在于协方差,在了解协方差矩阵前,需要了解下,为什么要有协方差这么个东西,这玩意儿到底有啥个用。
一些基本的概念,如平均数,方差、标准差(方差和标准差的公式跟之前的有稍微区别,平时见到的是这样的:,但是作者给出的是这样的:
)
I hear you asking “Why are you using n-1and not n?”. Well, the answer is a bit complicated, but in general,if your data set is a sample data set, ie. you have taken a subset of the real-world (like surveying 500 people about the election) then you must use n-1 because it turns out that this gives you an answer that is closer to the standard deviation that would result if you had used the entire population, than if you’d used n. If, however, you are not calculating the standard deviation for a sample, but for an entire population, then you should divide by n instead of n-1 . For further reading on this topic, the web page http://mathcentral.uregina.ca/RR/database/RR.09.95/weston2.html
describes standard deviation in a similar way, and also provides an example experiment that shows the difference between each of the denominators. It also discusses the difference between samples and populations.
想要深入了解的可以参考上述链接。
接上文,方差和标准差只能在当前维度或者说是一维独立的描述特性,但是如果想要看看不同的维度之前的平均数是否存在着某种联系话(比如每个学生,每周学习时间长度和期末考试得分是否存在着某种关系),方差和标准差显然不能来衡量不同维之前的关系。此时,协方差就可以登场了。
协方差(covariance)就是专门用来衡量两维数据中的关系,如果你对同一维的数据进行协方差计算,得到的就是这个维自身的方差。
方差的计算:
协方差公式:
含义:
“For each data item, multiply the difference between the x value and the mean of x, by the the difference between the y value and the mean of y.Add all these up, and divide by n-1”。
现在有一些学生的数据,表现学习时长和考试成绩,如下2副图所示:
这说明什么问题?从上2副图的精确数据中可以看到,协方差数据中如果,是正的(positive),表明同一条数据中的2维特征是同时增长的,如果是负的(negative),则表明当一个维中的数据增加时候,另一维的数据会减少。如果协方差是0的话,那么表明俩个维中的数据相互独立。
由于协方差可以计算同一数据集中任意两个维度特征的关系,所以对于高维数据样本来说,可以用协方差来找不同维之间的关系。
由此可以引出协方差矩阵(covariance Matrix)。
当数据的描述维度超过2个时候,比如拥有一个三维数据组成的集合,那么需要分别计算cov(x,y),cov(x,z) ,cov(y,z),对于一个维度为n的集合来说, 针对每个单独的样本,可以计算出个不同的协方差。
于是乎协方差矩阵:
对于三维特征数据来说,协方差矩阵:
更具公式,可以知道,cov(x,y)=cov(y,x)
所以,协方差矩阵是关于主对角线对称的。
为了解释后面的内容,得先回顾下一些矩阵相关的知识:
在矩阵,存在着这样的一种情况,
一个矩阵A乘以一个向量B后,得到一个常数C和原向量B,一般的把向量B称作矩阵A的特征向量(eigenvector),常数C就称作特征值(eigenvalue),以上针对非0情况,不考虑负数情况。
每一个特征向量和特征值都是一一对应的。
一般来说。这里的矩阵A都是方阵,也就是nxn。同时一个n X n的方阵具有n个特征值和对应的n个特征向量,同时如果A是对角矩阵的话,那么
,
表示特征值(解释这一节,有点点复杂,如果你强烈的兴趣去探究这些背后东西话,建议去搜下相关资料和基础知识,但是搞懂了话对理解PCA会非常有帮助的)
假如有一些二维特征的数据,
可以看到在x水平轴,样本方差远大与在y垂直轴的方差。协方差矩阵可能类似这样的:
如果样本是这样的情况话,
那么对应的协方差矩阵可能是样的:
对于,计算可以得到特征值
,
对应的特征向量:
对于,计算可以得到特征值:
一般 的,对于一个矩阵S来说,最大的几个特征值占的比例远超于其他的特征值,例如如果维数m=10,方差总和为100的话,T=100,那么将得到的特征值按照由大到小的顺序排列的话:
,可能
尽管是有10维的特征(跟上面的特征值注意区分),但是PCA会将此10维降到2位,因为90.5+8.9=99.4,已经占到总方差的99.4%了。
等等,特征值跟方差有何联系,注意到上面的(具体的数学证明自己可以单独去找资料,证明的就得展开很多东西,就不展开了http://math.stackexchange.com/questions/546155/proof-that-the-trace-of-a-matrix-is-the-sum-of-its-eigenvalues)
PCA解释:
在求得一系列的特征向量与特征向量
后,最大的
,比如
,这个
所对应的特征向量
表示什么意思呢?它表示或者解释了在新的特征中,最重要的方向,或者说新的误差最大方向,
表示第二重要的方向,以后以此类推。可以将原始数据中的维度m=10,经过PCA处理后,得到新的维度,其中
、
所对应的特征向量代表了这些方向或者特征。
再举一个实际例子:
有一些鸟的样本数据,特征分别为:length,wingspan,weight,样本数量一共100。
所以m=3,n=100
计算得到的协方差矩阵:
计算得矩阵特征值:以及特征值对应的特征向量
很明显,远大于其他特征值,他所对应的特征向量中的三个值表示什么意思呢?
怎么接着这个特征向量呢,可以用size来代替成为一个新的特征,而这个size受到length,wingspan,weight的影响,意味着size越大,那么length,wingspan,weight也相应越大,其中weight对size的影响最大,因为weight的值为0.88,大于0.41和0.22,同样的第二个特征值也是用来描述鸟的一个特性,这个特性主要受wingspan,weight影响(-0.46的绝对值是0.46,比0.25大),可以将这个特征看作stoutness。
也就是说原始数据中鸟的特征可以被新的2个特征来描述。
PCA将原始的n维数据,可以降到新的p维数据,其中p<=n
在得到新的特征后,将原始数据与新的特征做计算,就可以将原数据中n维降到p维了。
def pca(dataMat, topNfeat=9999999):
meanVals = mean(dataMat, axis=0)
meanRemoved = dataMat - meanVals #在新的坐标系中移除平均值
covMat = cov(meanRemoved, rowvar=0) #计算协方差
eigVals,eigVects = linalg.eig(mat(covMat)) #计算协方差矩阵特征值和特征向量
eigValInd = argsort(eigVals) #特征向量排序
eigValInd = eigValInd[:-(topNfeat+1):-1] #按照需求,选取重要的维
redEigVects = eigVects[:,eigValInd]
lowDDataMat = meanRemoved * redEigVects #降维
reconMat = (lowDDataMat * redEigVects.T) + meanVals
return lowDDataMat, reconMat</span>
主要参考:
http://www.math.union.edu/~jaureguj/PCA.pdf
http://www.cs.otago.ac.nz/cosc453/student_tutorials/principal_components.pdf