機器學習--降維技術PCA
1.PCA降維原理:
PCA屬於線性降維方式:
X為原空間 W為變化矩陣 Z為新空間 Z的維數要小於X維數,實現了降維處理。
用一個超平面來表示正交屬性空間的樣本點,這個超平面應該儘量滿足最近重構性以及最大可分性,即空間中所有點離這個超平面儘可能近,樣本點在超平面的投影儘可能區分開,基於最近重構性以及最大可分性,可以推匯出PCA分析就是對於矩陣XXT進行特徵值分解:
對於XXT特徵值分解之後,將特徵值排序,取前d`特徵值對應的特徵向量即為變換矩陣W
PCA第一個主成分選取資料差異性最大的方向,第二個主成分與第一個方向正交併且資料差異性次大的的方向,依次選取d`個主成分。
演算法流程如下所示: 樣本矩陣進行中心化 計算協方差矩陣XXT,對協方差矩陣進行特徵值分解,前d`大的特徵值對應的特徵向量組成變換矩陣W
2.PCA實現:
程式碼如下:
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
mean方法 axis = 0:壓縮行,對各列求均值,返回 1* n 矩陣 求各列的平均值
meanRemoved = dataMat - meanVals 中心化
covMat = cov(meanRemoved, rowvar=0) 如果rowvar為True(預設值),則每行代表一個變數,並在列中顯示(即每一列為一個樣本)。 否則,關係被轉置:每列代表變數,而行包含觀察值。
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
將特徵值有小到大排序,取最後幾個,以及對應的特徵向量組成變換矩陣redEigVects
lowDDataMat = meanRemoved * redEigVects#transform data into new dimensions 得到降維後的資料 reconMat = (lowDDataMat * redEigVects.T) + meanVals 重構原資料
載入資料集:
def loadDataSet(fileName, delim='\t'):
fr = open(fileName)
stringArr = [line.strip().split(delim) for line in fr.readlines()]
datArr = [list(map(float,line)) for line in stringArr]
return mat(datArr)
輸入資料樣本為二維資料,左邊為進行第一主成分分析後,重構後的新資料,可知資料沿方差最大方向;右邊為第一,第二主成分分析後重構資料,發現數據並沒有損失,因為本來資料集就是二維資料。
半導體制造資料PCA降維分析:
資料樣本:
資料中缺失資料的處理: 由於未知資料缺失處的含義,用0來代替不妥,可以使用非零的均值來代替缺失處資料。
求出第i列中非NAN資料的均值 將第i列中NAN處數值換成均值
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
觀察矩陣特徵值分解的特徵值如下:
可知資料的主要成分集中在前幾個特徵值,可以通過不斷測試選取不同的特徵值來測試方差百分比以及累計方差百分比來決定特徵向量的個數,依次來包含資料的絕大部分資訊。