数据集中含有太多特征时,需要简化数据。降维不是删除部分特征,而是将高维数据集映射到低维数据集,映射后的数据集更简洁,方便找出对结果贡献最大的部分特征。
简化数据的原因:
1、使得数据集更易使用
2、降低很多算法的计算开销
3、去除噪声
4、使得结果易懂
PCA:principal component analysis,主成分分析。数据从原来的坐标系转换到了新的坐标系,新坐标系的选择是由数据本身决定的。第一个新坐标轴选择的是原始数据中方差最大的方向,第二个新坐标轴的选择和第一个坐标轴正交且具有最大方差的方向。
PCA算法伪代码:
去除平均值 计算协方差矩阵 计算协方差矩阵的特征值和特征向量 将特征值从大到小排序 保留最大的N个特征值 将数据转换到上述N个特征向量构建的新空间中
代码:
from numpy import *
def loadDataSet(filename,delim='\t'):
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个特征。
