原理
主成分分析(PCA)搜索k个最能代表数据的n维正交向量,将原始数据投影到一个小得多的空间上,导致维归约。PCA是一种常用的降维方法,当我们在处理高维数据时,常常会对原始数据进行降维来降低难度和复杂度。降维需要遵守一定原则,即最能代表原始数据,即处理后数据尽可能不失真,那么被降掉的维度是冗余数据或者噪声。
自然界中噪声会影响我们听到真正有用的声音,在信息处理中也是如此。我们认为信息具有较大的协方差,噪声具有较小协方差,噪声的存在使得全体数据之间的相关性加强,数据不容易区分。
冗余数据对于区分数据样本不起作用,应该被降掉。
PCA算法
如何找到包含信息量大的数据?按照之前所说,信息和噪声的协方差区别很大,只要计算出协方差,协方差越大越有可能是所需要的数据。
去除平均值 计算协方差矩阵 计算协方差矩阵的特征值和特征向量 将特征值从大到小排序 保留最上面的N个特征向量 将数据转换到上述N个特征向量构建的新空间中
def pca(dataMat, topNfeat=9999999): meanVals = mean(dataMat, axis=0) meanRemoved = dataMat - meanVals #remove mean covMat = cov(meanRemoved, rowvar=0) eigVals,eigVects = linalg.eig(mat(covMat)) eigValInd = argsort(eigVals) #sort, sort goes smallest to largest eigValInd = eigValInd[:-(topNfeat+1):-1] #cut off unwanted dimensions redEigVects = eigVects[:,eigValInd] #reorganize eig vects largest to smallest lowDDataMat = meanRemoved * redEigVects#transform data into new dimensions reconMat = (lowDDataMat * redEigVects.T) + meanVals return lowDDataMat, reconMat
对于给的二维数据集,如果我们降为一个维度,降维后数据表示为红色部分。
导入半导体数据集进行测试,该数据集有590个特征,包含很多缺失值,先将缺失值设置为平均值。
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
应用PCA后,各成分的特征值如下。有很多为0,说明这些特征是冗余的。
将前20个特征值绘制出来,可以看到,前20个特征值都很大,
但由于数量级差别,转化为比值后,前四个成分包含了95%。
用坐标图也能看出,前四个成分包含绝大部分后,后面的成分可以看做冗余和噪声忽略不计。
总结
1. PCA算法作为一种数据预处理方法,在数据维度很高的情况下,提取主要维度来表示数据能提高算法效率。
2. 主成分的选取会影响后续计算,用绝大部分(比如99%)来代表所有仍然有误差。