【机器学习实战-python3】利用PCA简化数据

来源:互联网 发布:网络看江苏教育频道 编辑:程序博客网 时间:2024/06/05 17:50

本章是涉及降维主题的两章中的第一章。在降维中,我们对数据进行了预处理。之后,采用其他机器学习技术对其进行处理。
本篇的数据和代码参见:https://github.com/stonycat/ML-in-Action

一、降维技术概述
在已标注与未标注的数据上都有降维技术。这里我们将主要关注未标注数据上的降维技术,该技术同时也可以应用于已标注的数据。

大量的数据往往拥有超出显示能力的更多特征。数据显示并非大规模特征下的唯一难题,对数据进行简化还有如下一系列的原因:

使得数据集更易使用;降低很多算法的计算开销;去除噪声;使得结果易懂。

第一种降维的方法称为主成分分析(Principal Component Analysis,PCA)
在PCA中,数据从原来的坐标系转换到了新的坐标系,新坐标系的选择是由数据本身决定的。第一个新坐标轴选择的是原始数据中方差最大的方向,第二个新坐标轴的选择和第一个坐标轴正交且具有最大方差的方向。该过程一直重复,重复次数为原始数据中特征的数目。我们会发现,大部分方差都包含在最前面的几个新坐标轴中。因此,我们可以忽略余下的坐标轴,即对数据进行了降维处理。

另外一种降维技术是因子分析(Factor Analysis)。在因子分析中,我们假设在观察数据的生成中有一些观察不到的隐变量(latent variable)。假设观察数据是这些隐变量和某些噪声的线性组合。那么隐变量的数据可能比观察数据的数目少,也就是说通过找到隐变量就可以实现数据的降维。因子分析已经应用于社会科学、金融和其他领域中了。

还有一种降维技术就是独立成分分析(Independent Component Analysis,ICA)。ICA假设数据是从 N 个数据源生成的,这一点和因子分析有些类似。假设数据为多个数据源的混合观察结果,这些数据源之间在统计上是相互独立的,而在PCA中只假设数据是不相关的。同因子分析一样,如果数据源的数目少于观察数据的数目,则可以实现降维过程。

二、PCA

优点:降低数据的复杂性,识别最重要的多个特征。
缺点:不一定需要,且可能损失有用信息。
适用数据类型:数值型数据。

这里写图片描述
如上图所示,首先需要观察数据点的分布来判断如何映射坐标轴,这里是二维的,对坐标轴进行旋转,第一条坐标轴旋转到覆盖数据的最大方差位置,即图中的直线B。数据的最大方差给出了数据的最重要的信息。选择第二条坐标轴:假如该坐标轴与第一条坐标轴正交(orthogonal),它就是覆盖数据次大差异性的坐标轴。

坐标轴的旋转并没有减少数据的维度。降维就是选择合适的坐标维度来很好地划分数据。这里可以联想前面学习的SVM和决策树分类,但是对于分类超平面(高维度)却很难解释。

通过PCA进行降维处理,我们就可以同时获得SVM和决策树的u一样好。下图所示,降维能够在区分数据的同时降低数据维度。

这里写图片描述
在二维平面下,这一点看上去微不足道,但是如果在高维空间下则意义重大。
————————————————————————————————————————————

下面采用python3来实现PCA降维,幸运地,NumPy中有寻找特征向量和特征值的模块 linalg ,它有eig() 方法,该方法用于求解特征向量和特征值。将数据转换成前N个主成分的伪码大致如下:

去除平均值
计算协方差矩阵
计算协方差矩阵的特征值和特征向量
将特征值从大到小排序
保留最上面的N个特征向量
将数据转换到上述N个特征向量构建的新空间中

# -*- coding: utf-8 -*-from numpy import *def loadDataSet(fileName,delim='\t'):    fr=open(fileName)    #使用两个list来构建矩阵    stringArr=[line.strip().split(delim) for line in fr.readlines()]    datArr=[list(map(float,line)) for line in stringArr]    return mat(datArr)def pca(dataMat,topNfeat=9999999): #topNfeat为可选参数,记录特征值个数    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

测试:
这里写图片描述

可以看出,将2维的数据降到1维的直观图
降维数据图绘制

三、示例:利用 PCA 对半导体制造数据降维
半导体是在一些极为先进的工厂中制造出来的。如果制造过程中存在瑕疵,我们就必须尽早发现,从而确保宝贵的时间不会花费在缺陷产品的生产上。一些工程上的通用解决方案是通过早期测试和频繁测试来发现有缺陷的产品,但仍然有一些存在瑕疵的产品通过了测试。如果机器学习技术能够用于进一步减少错误,那么它就会为制造商节省大量的资金。

该数据包含很多的缺失值。这些缺失值是以NaN(Not a Number的缩写)标识的。下面我们用平均值来代替缺失值,平均值根据那些非NaN得到。

#将NaN替换成平均值def replaceNanWithMean():    datMat=loadDataSet('secom.data',' ')    numFeat=shape(datMat)[1]    for i in range(numFeat):        meanVal=mean(datMat[nonzero(~isnan(datMat[:,i].A))[0],i])        datMat[nonzero(isnan(datMat[:,i].A))[0],i]=meanVal    return datMat

这里写图片描述
…………
这里写图片描述
我们会看到一大堆值,但是其中的什么会引起我们的注意?我们会发现其中很多值都是0吗?实际上,其中有超过20%的特征值都是0。这就意味着这些特征都是其他特征的副本,也就是说,它们可以通过其他特征来表示,而本身并没有提供额外的信息。

接下来,我们了解一下部分数值的数量级。最前面15个值的数量级大于10 5 ,实际上那以后的值都变得非常小。这就相当于告诉我们只有部分重要特征,重要特征的数目也很快就会下降。

最后,我们可能会注意到有一些小的负值,它们主要源自数值误差应该四舍五入成0。
这里写图片描述

前六个主成分就覆盖了数据96.8%的方差,而前20个主成分覆盖了99.3%
的方差。这就表明了,如果保留前6个而去除后584个主成分,我们就可以实现大概100∶1的压缩比。另外,由于舍弃了噪声的主成分,将后面的主成分去除便使得数据更加干净。

有些人使用能包含90%信息量的主成分数量,而其他人使用前20个主成
分。我们无法精确知道所需要的主成分数目,必须通过在实验中取不同的值来确定。有效的主成分数目则取决于数据集和具体应用。
上述分析能够得到所用到的主成分数目,然后我们可以将该数目输入到PCA算法中,最后得到约简后数据就可以在分类器中使用了。

四、小结
降维技术使得数据变得更易使用,并且它们往往能够去除数据中的噪声,使得其他机器学习任务更加精确。降维往往作为预处理步骤,在数据应用到其他算法之前清洗数据。有很多技术可以用于数据降维,在这些技术中,独立成分分析、因子分析和主成分分析比较流行,其中又以主成分分析应用最广泛。

PCA可以从数据中识别其主要特征,它是通过沿着数据最大方差方向旋转坐标轴来实现的。选择方差最大的方向作为第一条坐标轴,后续坐标轴则与前面的坐标轴正交。协方差矩阵上的特征值分析可以用一系列的正交坐标轴来获取。

0 0
原创粉丝点击