《机器学习实战》笔记之十三——利用PCA来简化数据

第十三章  利用PCA来简化数据


主要内容
    • 降维技术
    • 主成分分析(PCA)
    • 对半导体数据进行降维处理

13.1降维技术

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

降维方法:

主成分分析(Principal Component Analysis, PCA)。数据从原来的坐标系转化到了新的坐标系,新坐标系的选择是由数据本身决定的。第一个新坐标轴选择的是原始数据中方差最大的方向,第二个新坐标轴的选择和第一个坐标轴正交且具有最大方差的方向。重复选择新坐标轴,最终大部分方差都包含在最前面的几个新坐标轴中。。因此,忽略余下的坐标轴,达到降维的目的。
因子分析(Factor Analysis)。在因子分析中,我们假定在观察数据的生成中有一些观察不到的隐变量(latent variable)。假设观察数据时这些隐变量和某些噪声的线性组合。通过找到隐变量就可以实现数据的降维。
独立主成分分析(Independent Component Analysis, ICA)。ICA假设数据是从N个数据源生成的。假设数据位多个数据源的混合观察结果,这些数据源之间在统计上是相互独立的,而在PCA中假设数据是不相关的。同因子分析一样,如果数据源的数目少于观察数据的数目,则可以实现降维过程。
流行学习(manifold learning)。

13.2PCA

原理:移动坐标轴

在PCA中,对数据的坐标进行旋转,该旋转的过程取决于数据的本身。

第一条坐标轴旋转到覆盖数据的最大方差位置,即直线B。数据的最大方差给出了数据的最重要的信息。
第二条坐标轴与第一条正交(orthogonal)。利用PCA,将数据坐标轴旋转至数据角度商的那些最重要的方向。

降维。旋转并没有减少数据的维度。第一个主成分是从数据差异性最大(即方差最大)的方向提取出来的。第二个主成分来自数据差异性次大的方向,并且该方向与第一个主成分方向正交。通过数据集的协方差矩阵及其特征值分析,即可得这些主成分的值。得到协方差矩阵的特征向量,保留最大的N个值,这些特征向量也给出了N个最重要特征的真实结构。将数据乘上这N个特征值对应的特征向量将其转换到新的空间。

在NumPy中实现PCA

数据:


Figure 13-3: testSet.txt数据
伪代码:
  • 去除平均值
  • 计算协方差矩阵
  • 计算协方差矩阵的特征值和特征向量
  • 将特征值从大到小排序
  • 保留最上面的N个特征向量
  • 将数据转换到上述N个特征向量构建的新空间中
代码:

#!/usr/bin/env python
# coding=utf-8
from numpy import *
import matplotlib
import matplotlib.pyplot as plt

def loadDataSet(fileName, delim = "\t"):
    fr = open(fileName)
    stringArr = [line.strip().split(delim) for line in fr.readlines()]
    datArr    = [map(float, line) for line in stringArr]#对每行数据的两个数字都变为float型
    return mat(datArr)

def pca(dataMat, topNfeat=9999999):                      #dataMat为1000×2的矩阵,
    meanVals    = mean(dataMat, axis=0)                  #numpy中的mat类型有算均值mean的方法,并且对每列进行计算,得到2*1的矩阵
    meanRemoved = dataMat - meanVals                     #平移到以0为中心的地方,避免均值影响。1000*2
    covMat      = cov(meanRemoved, rowvar = 0)           #计算协方差,维度为2,得到2×2的协方差矩阵
    eigVals, eigVects = linalg.eig(mat(covMat))          #计算特征值及特征向量,2×1,2×2,得到两个特征值,两列特征向量,向量长度为2
    eigValInd   = argsort(eigVals)                       #默认快排,从小到大进行排序
    eigValInd   = eigValInd[:-(topNfeat+1):-1]           #得到topNfeat个特征值,大的特征值排在前面,若topNfeat为1。,则取1个特征值
    redEigVects = eigVects[:, eigValInd]                 #将topNfeat个最大的特征值对应的那列向量取出来,若topNfeat为1,
    lowDDataMat = meanRemoved * redEigVects              #1000×2 * 2×topNfeat得到1000×topNfeat的低维空间的数据
    reconMat    = (lowDDataMat * redEigVects.T) + meanVals#1000×topNfeat * topNfeat*2 +1000×2重构数据
    return lowDDataMat, reconMat

dataMat = loadDataSet("testSet.txt")
lowDMat, reconMat = pca(dataMat, 1)
print shape(dataMat)
print shape(lowDMat)
print shape(reconMat)

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()

结果:
Figure 13-4: PCA降维效果

lowDMat矩阵为降维后的矩阵,大小为1000*topNfeat。
reconMat矩阵为重构数据的矩阵,也即将低维的lowDMat矩阵转到原来数据上,从上图看,lowDMat为一维坐标上的点(没画出来),其重构到数据上便是红色圆圈的点,即在二维空间里的点(在一条直线上),及reconMat矩阵。
若是topNfeat为2,即没有剔除任何特征,重构之后的数据会和原始的数据重合。

13.3示例:利用PCA对半导体制造数据降维

数据:

Figure 13-5: secom.data数据

缺失值处理:取平均值代替缺失值,平均值根据非NaN得到。
应用PCA:
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]) #values that are not NaN (a number)
        datMat[nonzero(isnan(datMat[:,i].A))[0],i] = meanVal  #set NaN values to mean
    return datMat

dataMat = replaceNanWithMean()
meanVals = mean(dataMat, axis=0)
meanRemoved = dataMat - meanVals
covMat      = cov(meanRemoved, rowvar=0)
eigVals, eigVects = linalg.eig(mat(covMat))
#print eigVals
print sum(eigVals)*0.9
print sum(eigVals[:6])
plt.plot(eigVals[:20])#对前20个画图观察
plt.show()
利用sklearn自带计算PCA的方法:
from sklearn import decomposition
pca_sklean = decomposition.PCA()
pca_sklean.fit(replaceNanWithMean())
main_var = pca_sklean.explained_variance_
print sum(main_var)*0.9
print sum(main_var[:6])
plt.plot(main_var[:20])
plt.show()

结果分析:


Figure 13-6: eigVals特征值中超过20%的值都为0






Figure 13-7: 我们编写的程序计算的主成分与sklean自带计算PCA得到主成分

前6个主成分覆盖了96.8%的方差,前20个主成分覆盖了99.3%的方差。如果保留前6个而去除后584个主成分,就可以实现大概100:1的压缩比。有效的主成分数目取决于数据集和具体应用。图13-7显示我们编写的程序得到主成分的90%为81131452.777与sklearn计算得出的81079677.7592相差不多。前6个也依然差不多。PS:统计的程序还没找,统计哪几个方差占主要部分比较重要,作者没给出来,需找下。


13.4小结

很多数据可用于降维:独立成分分析、因子分析和主成分分析。其中主成分分析应用最广泛。

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

#========

有关PCA具体的原理不再这里深入。另外,关于PCA的工具也有很多,sklearn里面就有降维的函数。还有LSI、流行学习等降维的方法,还有很多需要学习的地方。


  • 2
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 11
    评论
评论 11
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值