您的位置:首页 > 编程语言 > Python开发

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

2015-09-29 20:48 696 查看
第十三章  利用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、流行学习等降维的方法,还有很多需要学习的地方。
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息