数据集中含有太多特征时,需要简化数据。降维不是删除部分特征,而是将高维数据集映射到低维数据集,映射后的数据集更简洁,方便找出对结果贡献最大的部分特征。
简化数据的原因:
1、使得数据集更易使用
2、降低很多算法的计算开销
3、去除噪声
4、使得结果易懂
PCA:principal component analysis,主成分分析。数据从原来的坐标系转换到了新的坐标系,新坐标系的选择是由数据本身决定的。第一个新坐标轴选择的是原始数据中方差最大的方向,第二个新坐标轴的选择和第一个坐标轴正交且具有最大方差的方向。
PCA算法伪代码:
去除平均值 计算协方差矩阵 计算协方差矩阵的特征值和特征向量 将特征值从大到小排序 保留最大的N个特征值 将数据转换到上述N个特征向量构建的新空间中
代码:
from numpy import * def loadDataSet(filename,delim=' '): f=open(filename) stringArr=[line.strip().split(delim) for line in f.readlines()] dataArr=[list(map(float,line)) for line in stringArr] return mat(dataArr) def pca(dataMat,topNfeat=9999999): meanVals=mean(dataMat,0) meanRemoved=dataMat-meanVals covMat=cov(meanRemoved,rowvar=0) #默认把每行看成一个变量,rowvar=0表示把每列看成一个变量 eigVals,eigVects=linalg.eig(mat(covMat)) eigValInd=argsort(eigVals) eigValInd=eigValInd[:-(topNfeat+1):-1] redEigVects=eigVects[:,eigValInd] # print(redEigVects) lowDDatMat=meanRemoved*redEigVects reconMat=(lowDDatMat*redEigVects.T)+meanVals #协方差矩阵时对称矩阵,对称矩阵的特征向量的逆矩阵等于特征向量的转置矩阵 return lowDDatMat,reconMat
将原始数据和降维后的数据绘制成散点图:
def plotPoint(dataMat,reconMat): import matplotlib.pyplot as plt fig=plt.figure() ax=fig.add_subplot(111) ax.scatter(dataMat[:,0].flatten().A[0],dataMat[:,1].flatten().A[0],marker='^',c='r',s=30) ax.scatter(reconMat[:,0].flatten().A[0],reconMat[:,1].flatten().A[0],marker='*',c='y',s=10) plt.show()
测试:
dataMat=loadDataSet('testSet.txt') lowDMat,reconMat=pca(dataMat,1) plotPoint(dataMat,reconMat)
输出:
利用PCA对半导体制造数据降维过程中的空值处理:将空值替换成对应特征的平均值
def replaceNanWithMean(): dataMat=loadDataSet('secom.data',' ') numFeat=shape(dataMat)[1] for i in range(numFeat): meanVal=mean(dataMat[nonzero(~isnan(dataMat[:,i].A))[0],i]) dataMat[nonzero(isnan(dataMat[:,i].A))[0],i]=meanVal return dataMat
测试:
if __name__=='__main__': dataMat=replaceNanWithMean() lowDDatMat, reconMat=pca(dataMat,6) print(lowDDatMat[0])
输出:
[[5183.89616507+0.j 3022.64772377+0.j -688.38624272+0.j 57.92893142+0.j -349.28054496+0.j -41.1987254 +0.j]]
输出的是第一条记录,只保留了6个特征。