机器学习实战学习笔记(十二)利用PCA来简化数据

PS:该系列数据都可以在图灵社区(点击此链接)中随书下载中下载(如下)
机器学习实战学习笔记(十二)利用PCA来简化数据_第1张图片

1 降维技术

  对数据进行简化的原因:

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

  主成分分析(Principal Component Analysis,PCA): 在PCA中,数据从原来的坐标系转换到了新的坐标系,新坐标系的选择是由数据本身决定的。第一个新坐标轴选择的是原始数据中方差最大的方向,第二个新坐标轴的选择和第一个坐标轴正交且具有最大方差的方向。该过程一直重复,重复次数为原始数据中特征的数目。我们会发现,大部分方差都包含在最前面的几个新坐标轴中。因此,我们可以忽略余下的坐标轴,即对数据进行了降维处理。
  因子分析(Factor Analysis): 在因子分析中,我们假设在观察数据的生成中有一些观察不到的隐变量(latent variable)。假设观察数据是这些隐变量和某些噪声的线性组合。那么隐变量的数据可能比观察数据的数目少,也就是说通过找到隐变量就可以实现数据的降维。
  独立成分分析(Independent Component Analysis,ICA): ICA假设数据是从N个数据源生成的,这一点和因子分析有些类似。假设数据为多个数据源的混合观察结果,这些数据源之间在统计上是相互独立的,而在PCA中只假设数据是不相关的。同因子分析一样,如果数据源的数目少于观察数据的数目,则可以实现降维过程。

2 PCA

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

2.1 移动坐标轴

  第一个主成分就是数据差异性最大(即方差最大)的方向提取出来的,第二个主成分则来自于数据差异性次大的方向,并且该方向与第一个主成分方向正交。通过数据集的协方差矩阵及其特征值分析,我们就可以求得这些主成分的值。
  一旦得到了协方差矩阵的特征向量,我们就可以保留最大的N个值。这些特征向量也给出了N个最重要特征的真实结构。我们可以通过将数据乘上这N个特征向量而将它转换到新的空间。

2.2 在Numpy中实现PCA

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

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

  建立pca.py文件,编写如下代码用于计算PCA,并在python命令行进行测试:

import numpy as np
import matplotlib
import matplotlib.pyplot as plt

def loadDataSet(fileName, delim='\t'):
    with open(fileName, 'r') as fileObject:
        stringArr = [line.strip().split(delim) for line in fileObject.readlines()]
        datArr = [list(map(float, line)) for line in stringArr]
    return np.mat(datArr)

def pca(dataMat, topNfeat=9999999):
    #计算特征值和特征向量
    meanVals = np.mean(dataMat, axis=0)
    meanRomoved = dataMat - meanVals
    covMat = np.cov(meanRomoved, rowvar=0)
    eigVals, eigVects = np.linalg.eig(np.mat(covMat))
    #找出topNfeat个最大的特征向量
    #并利用这N个特征向量将原始数据转换到新空间
    eigValInd = np.argsort(eigVals)
    eigValInd = eigValInd[:-(topNfeat + 1) : -1]
    redEigVects = eigVects[:, eigValInd]
    lowDDataMat = meanRomoved * redEigVects
    reconMat = (lowDDataMat * redEigVects.T) + meanVals
    return lowDDataMat, reconMat

def plotPCA(fileName, topNfeat):
    dataMat = loadDataSet(fileName)
    lowDMat, reconMat = pca(dataMat, topNfeat)
    print("shape of lowDMat: ", np.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()

机器学习实战学习笔记(十二)利用PCA来简化数据_第2张图片
机器学习实战学习笔记(十二)利用PCA来简化数据_第3张图片
  可以看到上述结果对testSet.txt文件中的数据集进行了降维操作。

3 利用PCA对半导体制造数据降维

  secom.data文件中记录了半导体制造数据,它拥有590个特征。现在利用pca对这些特征进行降维处理。
  该数据包含很多缺失值。这些缺失值是NaN,这里用平均值代替,平均值根据那些非NaN得到。

def replaceNanWithMean():
    datMat = loadDataSet('secom.data', ' ')
    numFeat = np.shape(datMat)[1]
    for i in range(numFeat):
        #计算非NaN值的平均值,并将所有NaN替换为该平均值
        meanVal = np.mean(datMat[np.nonzero(~np.isnan(datMat[:, i].A))[0], i])
        datMat[np.nonzero(np.isnan(datMat[:, i].A))[0], i] = meanVal
    return datMat

  考虑在该数据集上应用PCA。首先确定所需特征和可以去除特征的数目。PCA会给出数据中所包含的信息量。数据(data)和信息(information)之前是有巨大的差别的。数据指的是接受的原始材料,其中可能包含噪声和不相关信息。信息是指数据中的相关部分。
机器学习实战学习笔记(十二)利用PCA来简化数据_第4张图片
机器学习实战学习笔记(十二)利用PCA来简化数据_第5张图片
  我们可以发现其中超过20%的特征值都是0,这意味着这些特征都是其他特征的副本,也就是说,它们可以通过其他特征来表示,而本身并没有提供额外的信息。又可以观察到很多值得数量级非常小,只有部分重要特征,重要特征的数目也很快就会下降。最后。我们可能会注意到有一些小的负值,它们主要源自数值误差应该四舍五入成0。
  下图给出总方差的百分比,发现,在开始几个主成分之后,方差就会迅速下降。
机器学习实战学习笔记(十二)利用PCA来简化数据_第6张图片
  可以看出大部分方差都包含在前面的几个主成分中,舍弃后面的主成分并不会损失太多的信息。如果保留前6个主成分,则数据集可以从590个特征约简成6个特征,大概实现了100:1的压缩。
  下表给出了这些主成分所对应的方差百分比和累积方差百分比。浏览“累积方差百分比(%)”这一列就会注意到,前六个主成分就覆盖了数据96.8%的方差,而前20个主成分覆盖了99.3%的方差。这就表明了如果保留前6个而去除后584个主成分,我们就可以实现大概100:1的压缩比。另外,由于舍弃了噪声的主成分,将后面的主成分去除便使得数据更加干净。
机器学习实战学习笔记(十二)利用PCA来简化数据_第7张图片

4 小结

  降维技术使得数据变得更易使用,并且它们往往能够去除数据中的噪声,使得其他机器学习任务更加精确。降维往往作为预处理步骤,在数据应用到其他算法之前清洗数据。有很多技术可以用于数据降维,在这些技术中,独立成分分析、因子分析和主成分分析比较流行,其中又以主成分分析应用最广泛。
  PCA可以从数据中识别其主要特征,它是通过沿着数据最大方差方向旋转坐标轴来实现的。选择方差最大的方向作为第一条坐标轴,后续坐标轴则与前面的坐标轴正交。协方差矩阵上的特征值分析可以用一系列的正交坐标轴来获取。

你可能感兴趣的:(机器学习)