机器学习第十三章:利用PCA来简化数据
2014-03-22 19:36
351 查看
一、降维技术
降维就是指采用某种映射方法,将原高维空间中的数据点映射到低维度的空间中。在低维空间下,数据更容易进行处理,如果降到三维以下,还可以将数据通过图像显示出来,因为人处在一个三维的空间。目前流行的降维方法有:主成分分析(Principal Component Analysis,PCA)、因子分析(Factor Analysis)、独立成分分析(IndependentComponent Analysis,ICA),其中PCA最为广泛。
二、PCA
它的目标是通过某种线性投影,将高维的数据映射到低维的空间中表示,并期望在所投影的维度上数据的方差最大,以此使用较少的数据维度,同时保留住较多的原数据点的特性。在PCA中,数据从原来的坐标系转换到新的坐标系,新坐标系中第一个坐标轴选择的是原始数据中方差最大的方向,第二个坐标轴选择的是和第一个坐标轴正交且具有最大方差的方向。该过程一直重复,重复次数为原始数据中特征的数目。那么问题出来了,为什么选择的坐标轴为方差最大的那个轴呢?
答案请看此文:/article/8492515.html
通过此文分析得出:
一、数据的最大方差给出了数据的最重要的信息
二、方差就是特征值,最佳的投影直线是特征值
最大时对应的特征向量,其次是
第二大对应的特征向量,依次类推。
三、保留特征值大(方差最大)的,而方差较小的特征(如噪声)被丢弃。
三 、在Numpy中实现PCA
主要思路:1、计算样本的平均值
即对原始变量进行中心化,因为协方差是离均差积和的平均,看公式
2、计算协方差矩阵
3、计算协方差矩阵的特征值和特征向量
4、将特征值从大到小排序
5、保留最大的特征值所对应的N个特征向量
6、将数据转换到上述N个特征向量构建的新空间中
源代码:
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] #把每行字符串映射为浮点型数字 ## print 'datArr=',datArr return mat(datArr) #返回的是矩阵型数据集 ''' 功能:将数据降维 输入变量: dataMat:矩阵型原始数据 topNfeat:保留的特征个数 输出变量: lowDDataMat:降维之后的数据集 reconMat:重构原始数据集 ''' def pca(dataMat, topNfeat=9999999): meanVals = mean(dataMat, axis=0) meanRemoved = dataMat - meanVals #remove mean移除均值 ## print 'meanRemoved=',meanRemoved covMat = cov(meanRemoved, rowvar=0) eigVals,eigVects = linalg.eig(mat(covMat)) ## print 'eigVals=',eigVals eigValInd = argsort(eigVals) #sort, sort goes smallest to largest eigValInd = eigValInd[:-(topNfeat+1):-1] #cut off unwanted dimensions后面的-1代表的是将值倒序,原来特征值从小到大,现在从大到小 ## print 'eigValInd=',eigValInd redEigVects = eigVects[:,eigValInd] #reorganize eig vects largest to smallest lowDDataMat = meanRemoved * redEigVects#transform data into new dimensions将数据转换到新空间中 print lowDDataMat reconMat = (lowDDataMat * redEigVects.T) + meanVals #降维后的数据再次映射到原来空间中,用于与原始数据进行比较 return lowDDataMat, reconMat ''' 功能:绘图 ''' def fig(dataMat,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() dataMat = loadDataSet('testSet.txt') print 'dataMat=',dataMat lowDMat, reconMat = pca(dataMat,1) ##print shape(lowDMat) print 'reconMat=',reconMat fig(dataMat,reconMat)
运行结果:
dataMat= [[ 10.235186 11.321997] [ 10.122339 11.810993] [ 9.190236 8.904943] [ 9.306371 9.847394] [ 8.330131 8.340352] [ 10.152785 10.123532] [ 10.40854 10.821986] [ 9.003615 10.039206] [ 9.534872 10.096991] [ 9.498181 10.825446] [ 9.875271 9.233426] [ 10.362276 9.376892] [ 10.191204 11.250851] [ 7.720499 6.4763 ] [ 9.334379 8.471268] [ 7.963186 6.731333] [ 8.244973 9.013785] [ 9.569196 10.568949] [ 8.854793 9.076536] [ 9.382171 7.240862]] lowDDataMat= [[-2.03871919] [-2.43596829] [ 0.59387316] [-0.31101859] [ 1.46595626] [-0.9152669 ] [-1.65671815] [-0.35894013] [-0.63321292] [-1.27985036] [ 0.00942306] [-0.32423664] [-1.95570875] [ 3.41431572] [ 0.92778767] [ 3.08125998] [ 0.88954941] [-1.07641315] [ 0.57796936] [ 2.02591845]] reconMat= [[ 10.21503446 11.33125395] [ 10.38085849 11.69223766] [ 9.11610923 8.9389944 ] [ 9.49383895 9.7612774 ] [ 8.75207485 8.1465249 ] [ 9.74607083 10.31036309] [ 10.05557545 10.98412629] [ 9.51384288 9.80482412] [ 9.6283328 10.05405819] [ 9.89825921 10.64166325] [ 9.36007672 9.47008928] [ 9.49935657 9.77328876] [ 10.18038335 11.25582165] [ 7.93876952 6.37603371] [ 8.97672301 8.63556338] [ 8.07779726 6.67868436] [ 8.99268484 8.67031081] [ 9.81333825 10.45679809] [ 9.12274796 8.95344632] [ 8.51832936 7.63768239]]
上面原始数据位20个样本,每个样本2个特征,保留1个特征,即降维到1维,其特征向量为方差最大的方向,就是如图红色直线的方向。