【Python机器学习】利用PCA来简化数据——PCA

PCA(主成分分析)的优缺点:

优点:降低数据的复杂性,识别最重要的多个特征;

缺点:不一定需要,且可能损失有用信息;

适用数据类型:数值型数据。

移动坐标轴

如下图,如果要求我们画出一条直线,这条线要尽可能覆盖这些点。

在PCA中,我们对数据的坐标进行旋转,该旋转的过程取决于数据的本身。第一条坐标轴旋转到覆盖数据的最大方差位置。数据的最大方差给出了数据的最重要信息。

在选择了覆盖数据最大差异化的坐标轴之后,我们选择第二条坐标轴。假如该坐标轴与第一条坐标轴垂直,它就是覆盖数据次大差异性的坐标轴。这里更严谨的说法是正交。利用PCA,我们将数据坐标轴旋转至数据角度上的那些最重要方向。

我们已经实现了坐标轴的旋转,接下来是降维。坐标轴的旋转并没有减少数据的维度。考虑上图的数据,其中包含3个不同的类别。要区分这3个类别,可以使用决策树。决策树是基于一个特征来做决策的。我们会发现,在x轴上可以找到一些值,这些值能够很好的将这3个类别分开。这样,我们就可能得到一些规则,比如当(x<4)时,数据属于类别0.如果使用SVM这样稍微复杂一些的分类器,我们就会得到更好地分类面和分类规则,比如当(w0*x+w1*y+b)>0时,数据也属于类别0.SVM可能比决策树得到更好的分类间隔,但是分类超平面时就很难解释。

通过PCA进行降维处理,我们就可以同时获得SVM和决策树的优点:一方面,得到了和决策树一样简单的分类器,同时分类间隔和SVM一样好。考虑到上图中的下半部分,其中的数据来自于上半部分并经PCA转换之后绘制而成的。如果仅使用原始数据,那么这里的间隔会比决策树的间隔更大。另外,由于只需要考虑一维信息,因此数据就可以通过比SVM简单得多的、很容易采用的规则进行区分。

还是上图的数据中,我们只需要一维信息即可,因为另一维信息只是对分类缺乏贡献的噪声数据。在二维平面下,这一点看上去微不足道,但是如果在高维空间下则意义重大。

通过数据集的协方差矩阵及其特征值的分析,我们可以求得这些主成分的值。一旦得到了协方差矩阵的特征向量,我们就可以保存最大的N个值。这些特征向量也给出了N个最重要特征的真实结构。我们可以通过将数据乘上这N个特征向量而将它转换到新的空间。

在NumPy中实现PCA

将数据转换成前N个主成分的伪代码大致如下:

去除平均值

计算协方差矩阵

计算协方差矩阵的特征值和特征向量

将特征值从大到小排序

保留最上面的N个特征向量

将数据转换到上述N个特征向量构建的新空间中

实际代码实现:

from numpy import *

def loadDataSet(fileName,delim='\t'):
    fr=open(fileName)
    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):
    meanVals=mean(dataMat,axis=0)
    #去除平均值
    meanRemoves=dataMat-meanVals
    covMat=cov(meanRemoves,rowvar=0)
    eigVals,eigVects=linalg.eig(mat(covMat))
    eigValInd=argsort(eigVals)
    #从小到大对N个值进行排序
    eigValInd=eigValInd[:-(topNfeat+1):-1]
    redEigVects=eigVects[:,eigValInd]
    #将数据转换到新空间
    lowDDateMat=meanRemoves*redEigVects
    reconMat=(lowDDateMat*redEigVects.T)+meanVals
    return lowDDateMat,reconMat

上述代码包含了通常的NumPy导入和loadDataSet()函数。这里的loadDataSet使用了两个list comprehension来构建矩阵。

pac()函数有两个参数:第一个参数适用于进行PCA操作的数据集,第二个参数topNfeat则是一个可选参数,即应用的N个特征。如果不指定topNfeat的值,那么函数就会返回前9999999个特征,或者原始数据中全部非特征。

pca()函数首先计算并减去原始数据集的平均值。然后,计算协防差矩阵及其特征值,接着利用argsort()函数对特征值进行从小到大的排序。根据特征值排序结果的逆序就可以得到topNfeat个最大的特征向量。这些特征向量将构成后面对数据进行转换的矩阵,该矩阵则利用N个特征将原始数据转换到新空间中。最后,原始数据被重构后返回用于调试,同时降维之后的数据集也被返回了。

我们在testSet.txt文件中加入一个由1000个数据点组成的数据集,在这个数据集上进行PCA操作查看运行效果:

dataMat=loadDataSet('test/testSet.txt')
lowDMat,reconMat=pca(dataMat,1)
print(shape(lowDMat))

可以看到,降维之后的矩阵是一个一维矩阵。

我们将降维后的数据和原始数据一起绘制出来:

import matplotlib.pyplot as plt

fig=plt.figure()
ax=fig.add_subplot(111)
ax.scatter(dataMat[:,0].flatten().A[0],dataMat[:,1].flatten().A[0],marker='^',s=90)
ax.scatter(reconMat[:,0].flatten().A[0],reconMat[:,1].flatten().A[0],marker='o',s=50,c='red')
plt.show()

调整参数,观察不同的结果:

dataMat=loadDataSet('test/testSet.txt')
lowDMat,reconMat=pca(dataMat,2)

import matplotlib
import matplotlib.pyplot as plt

fig=plt.figure()
ax=fig.add_subplot(111)
ax.scatter(dataMat[:,0].flatten().A[0],dataMat[:,1].flatten().A[0],marker='^',s=90)
ax.scatter(reconMat[:,0].flatten().A[0],reconMat[:,1].flatten().A[0],marker='o',s=50,c='red')
plt.show()

可以看到,设置两个特征值的话,数据就会和原始数据重合。

  • 23
    点赞
  • 8
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值