1. 程式人生 > >Principal Component Analysis(主成分分析)

Principal Component Analysis(主成分分析)

PCA原理:

這裡寫圖片描述這裡寫圖片描述

通常情況下,在收集資料集時會有很多的特徵,這代表著資料是高冗餘的表示,但是對於某個工程來說其實可能並不需要那麼多的特徵。所以就需要給資料進行降維(Dimensionality Reduction)。降維可以簡化資料,使資料集更易使用,降低時間開銷,而且能減少一部分噪音的影響,使最後的效果變好。比如上圖中,如果進行降維後再進行分類,將會易於處理。
主成分分析(Principal Component Analysis,PCA),顧名思義就是找出最主要的成分來代替就好,那麼如何選擇最主要的成分來代替能使誤差最小呢?即如何選擇能最大的代替原來的資料。

這裡寫圖片描述

PCA的目的就是找到一個方向向量,當我們投影在這個方向上時,希望它的方差儘可能大,均方誤差儘可能的小,這樣做可以保證所有的點都儘可能的離這條線近。比如在上圖,不用想也能明白哪一個方向是最好的。不過這裡的均方誤差,有必要和線性迴歸的代價函式做一下比較,一個是投影誤差,一個是預測誤差。

這裡寫圖片描述

為了將資料從原來的座標系轉移到了新的座標系,新的座標系將由資料本身決定,第一個新座標是方差最大的方向,其他的是與第一個方向方向正交且具有最大方差的方向。因為發現大部分方差都包含在前幾個新座標中,因此可以忽略餘下的座標軸,從而保證了資料的特徵的最小損失。那麼可以求出其協方差矩陣來判斷。證明一下,如果對於任意一個點 xi ,可得其在新的座標系中的投影為 WTxi ,投影方差為 WTxixTiW ,那麼最大化 i=1mWTxixTiW

即可。輕鬆可知 XXTW=λW 。即算出其協方差矩陣就行了,然後保留最重要的幾個特徵,將資料進行轉換降維就完成了。

演算法實現:(Python)

def pca(dataMat, topNfeat=9999999):#topNfeat是應用的前N個特徵,不指定就返回前999999
    meanVals = mean(dataMat, axis=0)
    meanRemoved = dataMat - meanVals #去平均值
    covMat = cov(meanRemoved, rowvar=0)#協方差
    eigVals,eigVects = linalg.eig(mat(covMat))#特徵值
eigValInd = argsort(eigVals)#從小到大排序 eigValInd = eigValInd[:-(topNfeat+1):-1] redEigVects = eigVects[:,eigValInd]#topN的特徵向量 lowDDataMat = meanRemoved * redEigVects#轉換新空間 reconMat = (lowDDataMat * redEigVects.T) + meanVals return lowDDataMat, reconMat

PCA應用:
PCA引數說明:
PCA(copy=True, iterated_power=’auto’, n_components=None, random_state=None,svd_solver=’auto’, tol=0.0, whiten=False)

copy=True:是否複製
iterated_power='auto':迭代
n_components=None:降維特徵數目
random_state=None:隨機狀態
svd_solver='auto':自否採用SVD
tol=0.0:容忍度
whiten=False:是否特徵歸一化
from sklearn import datasets
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA#匯入PCA模組
from mpl_toolkits.mplot3d import Axes3D#繪製3D散點圖
from pylab import *
mpl.rcParams['font.sans-serif'] = ['SimHei'] 
mpl.rcParams['axes.unicode_minus'] = False 

iris=datasets.load_iris()

x=iris.data[:,1]
y=iris.data[:,2]
species=iris.target
x_reduced=PCA(n_components=3).fit_transform(iris.data)

fig=plt.figure()
ax=Axes3D(fig)
ax.set_title('基於iris資料集的PCA',size=14)#設定題目
ax.scatter(x_reduced[:,0],x_reduced[:,1],x_reduced[:,2],c=species)

ax.set_xlabel('第一維特徵')#設定x軸標籤
ax.set_ylabel('第二維特徵')
ax.set_zlabel('第三維特徵')
ax.w_xaxis.set_ticklabels(())#去除刻度文字,便於觀察資料
ax.w_yaxis.set_ticklabels(())
ax.w_zaxis.set_ticklabels(())
plt.show()

這裡寫圖片描述

現在讓我們換個角度理解PCA,PCA的目的不就是找個新的基座標來減少維度(自由度)嗎?然後再根據基座標重建整個資料。那麼目標函式就可以變為了要最小化這個重建的誤差,然後同樣的也可以推匯出類似上面方法的目標形式。那麼關鍵是這個視角與第一種的差距在哪呢?可以看出一個是為了找主成分,一個直接進行維度縮減。所以其實從某種角度上來看,這個視角或許才是更適合PCA降維的理解。

這裡寫圖片描述

《Deep Learning》一書中打過的比方–烙餅空間(Pancake), 而在烙餅空間裡面找一個線性流行就是PCA的另一種理解,即把資料概率值看成是空間!!

這裡寫圖片描述
這裡寫圖片描述