zoukankan      html  css  js  c++  java
  • Python 主成分分析PCA

      主成分分析(PCA)是一种基于变量协方差矩阵对数据进行压缩降维、去噪的有效方法,PCA的思想是将n维特征映射到k维上(k<n),这k维特征称为主元,是旧特征的线性组合,这些线性组合最大化样本方差,尽量使新的k个特征互不相关。

    相关知识

    介绍一个PCA的教程:A tutorial on Principal Components Analysis ——Lindsay I Smith

    1.协方差 Covariance

      变量X和变量Y的协方差公式如下,协方差是描述不同变量之间的相关关系,协方差>0时说明 X和 Y是正相关关系,协方差<0时 X和Y是负相关关系,协方差为0时 X和Y相互独立。

      

      协方差的计算是针对两维的,对于n维的数据集,可以计算C(n,2)种协方差。 n维数据的协方差矩阵的定义如下:
      
          Dim(x)表示第x维。

          对于三维(x,y,z),其协方差矩阵如下,可看出协方差矩阵是一个对称矩阵(symmetrical),其对角线元素为每一维的方差:
        

    2.特征向量和特征值 

      ,则称是A的特征值,X是对应的特征向量。可以这样理解:矩阵A作用在它的特征向量X上,仅仅使得X的长度发生了变化,缩放比例就是相应的特征值。特征向量只能在方阵中找到,而且并不是所有的方阵都有特征向量,并且如果一个n*n的方阵有特征向量,那么就有n个特征向量。一个矩阵的所有特征向量是正交的,即特征向量之间的点积为0,一般情况下,会将特征向量归一化,即向量长度为1。

    3.PCA过程

      第一步,获取数据,下图中的Data为原始数据,一共有两个维度,可看出二维平面上的点。

      

      下图是Data在二维坐标平面上的散点图:

      

      第二步,减去平均值,对于Data中的每一维数据分别求平均值,并减去平均值,得到DataAdjust数据。

      第三步,计算DataAdjust的协方差矩阵

      

      第四步,计算协方差矩阵的特征向量和特征值,选取特征向量

      
       

      特征值0.490833989对应的特征向量是(-0.735178656, 0.677873399),这里的特征向量是正交的、归一化的,即长度为1。

      下图展示DataAdjust数据和特征向量的关系:

      

      正号表示预处理后的样本点,斜着的两条线就分别是正交的特征向量(由于协方差矩阵是对称的,因此其特征向量正交),特征值较大的那个特征向量是这个数据集的主要成分(principle component)。通常来说,当从协方差矩阵计算出特征向量之后,下一步就是通过特征值,对特征向量进行从大到小的排序,这将给出成分意义的顺序。成分的特征值越小,其包含的信息量也就越少,因此可以适当选择。  

      如果数据中有n维,计算出n个特征向量和特征值,选择前k个特征向量,然后最终的数据集合只有k维,取的特征向量命名为FeatureVector。 

         

      这里特征值只有两个,我们选择其中最大的那个,1.28402771,对应的特征向量是clip_image009[6]

      第五步,将样本点投影到选取的特征向量上,得到新的数据集

      假设样例数为m,特征数为n,减去均值后的样本矩阵为DataAdjust(m*n),协方差矩阵是n*n,选取的k个特征向量组成的矩阵为EigenVectors(n*k)。那么投影后的数据FinalData为

           clip_image011[4] 

      这里是FinalData(10*1) = DataAdjust(10*2矩阵)×特征向量clip_image009[7]

      得到结果为

      clip_image012[4]

      下图是FinalData根据最大特征值对应的特征向量转化回去后的数据集形式,可看出是将DataAdjust样本点分别往特征向量对应的轴上做投影:

      

      如果取的k=2,那么结果是

         clip_image014[4]

      可见,若使用了所有特征向量得到的新的数据集,转化回去之后,与原来的数据集完全一样(只是坐标轴旋转)。

    Python实现PCA

      将数据转化成前K个主成分的伪码大致如下: 

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

      代码实现如下:

    from numpy import *
    
    def loadDataSet(fileName, delim='	'):
        fr = open(fileName)
        stringArr = [line.strip().split(delim) for line in fr.readlines()]
        datArr = [map(float,line) for line in stringArr]
        return mat(datArr)
    
    def pca(dataMat, topNfeat=999999):
        meanVals = mean(dataMat, axis=0)
        DataAdjust = dataMat - meanVals           #减去平均值
        covMat = cov(DataAdjust, rowvar=0)
        eigVals,eigVects = linalg.eig(mat(covMat)) #计算特征值和特征向量
        #print eigVals
        eigValInd = argsort(eigVals)
        eigValInd = eigValInd[:-(topNfeat+1):-1]   #保留最大的前K个特征值
        redEigVects = eigVects[:,eigValInd]        #对应的特征向量
        lowDDataMat = DataAdjust * redEigVects     #将数据转换到低维新空间
        reconMat = (lowDDataMat * redEigVects.T) + meanVals   #重构数据,用于调试
        return lowDDataMat, reconMat

      测试数据testSet.txt由1000个数据点组成。下面对数据进行降维,并用matplotlib模块将降维后的数据和原始数据一起绘制出来。

    import matplotlib
    import matplotlib.pyplot as plt
    
    dataMat = loadDataSet('testSet.txt')
    lowDMat, reconMat = pca(dataMat,1)
    print "shape(lowDMat): ",shape(lowDMat)
    
    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()

      结果如下图:

    Python环境

    1.编译环境:win8.1 + 32位 + python2.7

    2.相关模块安装:

      (1)Numpy和Scipy:numpy用于存储和处理大型矩阵,进行数值计算。scipy是基于numpy的科学和工程计算工具,用于处理多维数组向量、矩阵、图形(图形图像是像素的二维数组)、表格。下载地址:http://www.scipy.org/scipylib/download.html

      (2)Matplotlib:python的一个图形框架,用于数据绘图。win32的安装文件下载地址:http://matplotlib.org/downloads.html

      (3)Dateutil 和 Pyparsing模块:安装配置matplotlib包时需要。win32的安装文件下载地址:http://www.lfd.uci.edu/~gohlke/pythonlibs/

    3.编译遇到问题:

      (1)提示“No module name six”,将Python27Libsite-packagesscipylib中的six.py six.pyc six.pyo三个文件拷贝到Python27Libsite-packages目录下即可。

      (2)提示 “ImportError: six 1.3 or later is required; you have 1.2.0”,说明six.py版本过低,下载最新的版本,将其中的six.py替换Python27Libsite-packages中的six.py即可,下载地址:https://pypi.python.org/pypi/six/

      注:six模块是Python 2和3的兼容工具

    PCA可以从数据中识别其主要特征,它是通过沿着数据最大方差方向旋转坐标轴来实现的。其中的矩阵运算,求特征值、特征向量等不是很熟悉,仍需进一步学习。

  • 相关阅读:
    204. Count Primes (Integer)
    203. Remove Linked List Elements (List)
    202. Happy Number (INT)
    201. Bitwise AND of Numbers Range (Bit)
    200. Number of Islands (Graph)
    199. Binary Tree Right Side View (Tree, Stack)
    198. House Robber(Array; DP)
    191. Number of 1 Bits (Int; Bit)
    190. Reverse Bits (Int; Bit)
    189. Rotate Array(Array)
  • 原文地址:https://www.cnblogs.com/chenbjin/p/4200790.html
Copyright © 2011-2022 走看看