數據集中含有太多特征時,需要簡化數據。降維不是刪除部分特征,而是將高維數據集映射到低維數據集,映射后的數據集更簡潔,方便找出對結果貢獻最大的部分特征。
簡化數據的原因:
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個特征。