一.PCA基礎
線性映射(或線性變換),簡單的來說就是將高維空間數據投影到低維空間上,那么在數據分析上,我們是將數據的主成分(包含信息量大的維度)保留下來,忽略掉對數據描述不重要的成分。即將主成分維度組成的向量空間作為低維空間,將高維數據投影到這個空間上就完成了降維的工作。
在 PCA中,數據從原來的坐標系轉換到了新的坐標系,新坐標系的選擇是由數據本身決定的。第一個新坐標軸選擇的是原始數據中方差最大的方向,第二個新坐標軸的選擇和第一個坐標軸正交且具有最大方差的方向。該過程一直重復,重復次數為原始數據中特征的數目。我們會發現,大部分方差都包含在最前面的幾個新坐標軸中。因此,我們可以忽略余下的坐標軸,即對數據進行了降維處理。
工作原理:
①找出第一個主成分的方向,也就是數據 方差最大 的方向。
②找出第二個主成分的方向,也就是數據 方差次大 的方向,並且該方向與第一個主成分方向正交(果是二維空間就叫垂直)。
③通過這種方式計算出所有的主成分方向。
④通過數據集的協方差矩陣及其特征值分析,我們就可以得到這些主成分的值。
⑤一旦得到了協方差矩陣的特征值和特征向量,我們就可以保留最大的 N 個特征。這些特征向量也給出了 N 個最重要特征的真實結構,我們就可以通過將數據乘上這 N 個特征向量 從而將它轉換到新的空間上。
二.PCA在NumPy中的實現
def loadDataSet(fileName, delim='\t') : fr = open(fileName) stringArr = [line.strip().split(delim) for line in fr.readlines()] dataArr = [map(float, line) for line in stringArr] return mat(dataArr) # dataMat: 用於進行PCA操作的數據集 # topNfeat: 可選參數,即應用的N個特征。 # 若不指定topNfeat的值,那么函數就會返回前9999999個特征,或者原始數據中的全部特征 def pca(dataMat, topNfeat=9999999) : # 計算平均值 meanVals = mean(dataMat, axis=0) # 減去原始數據的平均值 meanRemoved = dataMat - meanVals # 計算協方差矩陣及其特征值 covMat = cov(meanRemoved, rowvar=0) eigVals, eigVects = linalg.eig(mat(covMat)) # 利用argsort()函數對特征值進行從小到大的排序,根據特征值排序結果的逆序就可以得到 # topNfeat個最大的特征向量 eigValInd = argsort(eigVals) eigValInd = eigValInd[:-(topNfeat+1):-1] # 這些特征向量將構成后面對數據進行轉換的矩陣,該矩陣則利用N個特征將原始數據轉換到新空間中 redEigVects = eigVects[:, eigValInd] lowDDataMat = meanRemoved * redEigVects reconMat = (lowDDataMat * redEigVects.T) + meanVals return lowDDataMat, reconMat
注意:與python2有點不同,python3要加list
>>> dataMat = pca.loadDataSet('testSet.txt') >>> lowDMat, reconMat = pca.pca(dataMat, 1) >>> import numpy >>> numpy.shape(lowDMat) (1000, 1) >>> import matplotlib >>> 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='^', s=90) <matplotlib.collections.PathCollection object at 0x000002449DCFA2B0> >>> ax.scatter(reconMat[:,0].flatten().A[0], reconMat[:,1].flatten().A[0], marker='o', s=50, c='red') <matplotlib.collections.PathCollection object at 0x000002449DCFABE0> >>> plt.show()
得到如圖
三.利用PCA對半導體制造數據降維
def replaceNaNWithMean(): #解析數據 datMat=loadDataSet('secom.data',' ') #獲取特征維度 numFeat=shape(datMat)[1] #遍歷數據集每一個維度 for i in range(numFeat): #利用該維度所有非NaN特征求取均值 meanVal=mean(datMat[nonzero(~isnan(datMat[:,i].A))[0],i]) #將該維度中所有NaN特征全部用均值替換 datMat[nonzero(isnan(datMat[:,i].A))[0],i]=meanVal return datMat dataMat=replaceNaNWithMean() meanVals=mean(dataMat,axis=0) meanRemoved=dataMat-meanVals conMat=cov(meanRemoved,rowvar=0) eigVals,eigVects=linalg.eig(mat(covMat)) eigVects
結果出現錯誤
錯誤有待解決,也希望知道原因的小伙伴能告知一下,非常感謝