主成分分析PCA

文章推薦指數: 80 %
投票人數:10人

主成分分析(Principal Component Analysis, PCA)最主要是利用數學的方法,將複雜的事情簡化之。

主成分分析在100 年前由英國數學家卡爾·皮爾森發明, ... 主成分分析 主成分分析(Principal Component Analysis, PCA)最主要是利用數學的方法,將複雜的事情簡化之。

主成分分析在100年前由英國數學家卡爾·皮爾森發明,是一個至今仍在機器學習與統計學領域中被廣泛用來分析資料、降低數據維度以及去關聯的線性降維方法。

說穿了,主成分分析就是要把二維平面降成一維的線。

而三維立體空間呢,則降成二維平面,甚至也可以再降成一條線。

再進階一點,把四維降成三維,二維,或一維。

100維也可以降成一維,二維,三維,隨便你高興的降。

那麼,怎麼降呢?,應該有一定的SOP吧!!對,這個SOP就是最短距離,也就是投影距離。

OK,主成分分析就是去除不想要知道的成份,只留下想知道的資訊。

本篇只說明PCA的基本原理,並不去討論它的演算法,因為演算法需要有高等數學的涵養才看得懂. 此篇雖不說明其演算法,但相關基礎數學還是必需知道,請先研讀基礎數學這篇說明 產生資料 首先產生20組數字資料以便方便日後說明,底下為產生20組數字的程式.  importnumpyasnpimportpylabasplt#只顯示小數點下兩位數字,但實際還是以原始值計算np.set_printoptions(precision=2)#偽隨機產生器,每次重頭開始執行其值都一樣rng=np.random.RandomState(1)W=rng.rand(2,2)#產生二列20行的隨機數X_normal=rng.normal(scale=5,size=(2,20))#將W與X_normal相乖,[2,2]*[2,20]=[2,20]X_orig=W@X_normal#計算每列的平均值,再轉成二維陣列X_mean=X_orig.mean(axis=1)[:,np.newaxis]X=X_orig-X_meanprint(X)plt.xlim(-8,8)plt.ylim(-8,8)plt.scatter(X[0],X[1])plt.show()結果:[[2.890.325.8-6.523.94-4.210.452.141.3-4.98-2.4-3.10.69-1.59-3.64-0.246.814.63-2.24-0.06][1.520.911.52-0.88-0.03-1.26-0.250.96-0.89-0.45-0.88-1.12-0.860.13-1.530.512.661.28-0.14-1.19]] 代表線 上述那個圖,所有的點呈現足漸往上的趨勢。

那麼,下面到底那一條線才最具資格代表所有的點呢?藍色?綠色?紅色? RE值 什麼是最具資格的代表線呢?這句話太模糊了,所以需要定義一下。

定義:所有的點,垂直投射到某一線條時,點與線的垂直距離加總值,我們稱為RE值。

若RE值為最小,則稱此線為最具代表的線,又稱為PCA線。

如下圖黃色線的加總,為RE值。

上圖中,假設紅色線的向量值為$(\begin{bmatrix}0.97\\0.25\end{bmatrix})$,則(2.89,1.52)這個點投影到紅色向量線後,座落到紅色線的長度,可以使用投影矩陣計算出來$(\begin{bmatrix}2.89,1.52\end{bmatrix}*\begin{bmatrix}0.97\\0.25\end{bmatrix}=3.18)$ 這是一個非常神奇的事,試想想,不需要計算sin,cos耶 v=np.array([0.9691344,0.246533])[np.newaxis,:]L=v@Xprint(L)結果:[[3.180.535.99-6.533.81-4.390.372.311.04-4.93-2.54-3.280.46-1.51-3.9-0.117.264.81-2.2-0.35]] 那麼,上述$(\vec{v}=\begin{bmatrix}0.97\\0.25\end{bmatrix})$是怎麼出來的呢。

在Python中只需使用PCA方法即可算出3.18這個長度,根本不需要去管他是怎麼算出來的。

如下代碼所示 pca_1d=PCA(1,random_state=9527)pca=pca_1d.fit_transform(X.T).Tprint(pca)結果同上[[3.180.535.99-6.533.81-4.390.372.311.04-4.93-2.54-3.280.46-1.51-3.9-0.117.264.81-2.2-0.35]] PCA向量 上面說過pca演算法是怎麼算的不用管,直接由PCA的演算法即可得知。

但是$(\begin{bmatrix}0.97\\0.25\end{bmatrix})$這個值還是需要跟大家交代一下。

此值必需使用如下三角函數及反三角函數來計算。

上述的橘色線為pca線,由(2.89,1.52)這個點投射後的長度為3.18(經由上述PCA方法算出來的)。

再由X2線與pca正交後的座標為(nx,ny)。

由上述的資料可以算出x1,及x2。

o3角度=(o1+o2)=np.degrees(np.arcsin(1.52/x1))o1角度=np.degrees(np.arcsin(x2/x1)) 所以就可以算出o2角度=o3-o1。

即然知道o2的角度後,那麼pca線長度為1時,(x,y)的座標值為多少呢?nx=cos(o2)ny=sin(o2)所以$(\vec{pca}=\begin{bmatrix}cos(o2)\\sin(o2)\end{bmatrix})$即為pca線的向量值 PCA與迴歸線 下面的代碼,是想表示PCA線其實跟迴歸線相當的接近 importnumpyasnpimportpylabaspltfromsklearn.decompositionimportPCA#只顯示小數點下兩位數字,但實際還是以原始值計算np.set_printoptions(precision=2)#偽隨機產生器,每次重頭開始執行其值都一樣rng=np.random.RandomState(1)w=rng.rand(2,2)#產生二列20行的隨機數x_normal=rng.normal(scale=5,size=(2,20))#將W與X_normal相乖,[2,2]*[2,20]=[2,20]x_org=w@x_normal#計算每列的平均值,再轉成二維陣列x_mean=x_org.mean(axis=1)[:,np.newaxis]x=x_org-x_meanmodel=PCA(1,random_state=1)model.fit(x)pca=model.fit_transform(x.T).Tprint("PCA計算出來的投影值:\n",pca)#計算pca向量a=x[0,0]b=x[1,0]c=pca[0][0]x1=pow(a*a+b*b,1/2)x2=pow(x1*x1-c*c,1/2)o3=np.degrees(np.arcsin(b/x1))o1=np.degrees(np.arcsin(x2/x1))o2=o3-o1ny=1*np.sin(np.pi/180*o2)nx=1*np.cos(np.pi/180*o2)print("pca向量值:",nx,ny)v=np.array([[nx,ny]])l=v@xprint("手動算出pca向量的投影值:\n",l)title=['PCA','REG','X','Y']#畫pca線plt.plot([nx*-8,nx*8],[ny*-8,ny*8])#迴歸線f=np.poly1d(np.polyfit(x[0],x[1],1))plt.plot(x[0],f(x[0]))plt.xlim(-8,8)plt.ylim(-8,8)plt.plot([-8,8],[0,0],c='green')plt.plot([0,0],[-8,8],c='green')plt.scatter(x[0],x[1])plt.legend(title,bbox_to_anchor=(0.98,1),loc=2,borderaxespad=0.)plt.show()結果:PCA計算出來的投影值:[[3.180.535.99-6.533.81-4.390.372.311.04-4.93-2.54-3.280.46-1.51-3.9-0.117.264.81-2.2-0.35]]pca向量值:0.96913438934617570.2465330310254901手動算出pca向量的投影值:[[3.180.535.99-6.533.81-4.390.372.311.04-4.93-2.54-3.280.46-1.51-3.9-0.117.264.81-2.2-0.35]] 降維 將20個點的(x,y)二維座標(共40個數字),投射到一條線的一維座標(變成20個數字),稱為降維。

那麼如果是20個點的三維立體空間座標,則共有60個數字,然後投射到二維的平面時,就會變成只有40個數字。

那麼三維的立體空間可以投射成一條線嗎?這叫廢話,當然可以。

此時,60個數字就會變成20個數字了。

再進階一點,如果是20個點的100維度呢,那麼就有2000個數字,投射到一維時,還是20個數字。

Scikit-learndigits資料視覺化 底下是scikit的digits資料,每筆資料有64個維度,然後降成二維的圖形 fromsklearnimportdatasetsfromsklearn.decompositionimportPCAimportmatplotlib.pyplotaspltdigits=datasets.load_digits()colors=['black','blue','purple','yellow','white','red','lime','cyan','orange','gray']pca=PCA(n_components=2)#Fitandtransformthedatatothemodelreduced_data_pca=pca.fit_transform(digits.data)foriinrange(len(colors)):x=reduced_data_pca[:,0][digits.target==i]y=reduced_data_pca[:,1][digits.target==i]plt.scatter(x,y,c=colors[i])plt.legend(digits.target_names,bbox_to_anchor=(1.05,1),loc=2,borderaxespad=0.)plt.xlabel('FirstPrincipalComponent')plt.ylabel('SecondPrincipalComponent')plt.title("PCAScatterPlot")plt.show()   參考:https://leemeng.tw/essence-of-principal-component-analysis.html 文章導覽 特徵資料庫K-MeansClustering 個人資訊 暱稱:ThomasWu eMail:[email protected] 本站搜尋 Searchfor: Search 分類 Android(92) Java版(68) AdnroidApp高階(8) AndroidApp初階(17) AndroidApp進階(10) AndroidMSSQL(3) AndroidMySQL(2) AndroidOpenGLES(7) Android發怖(4) Android其他(4) Android圖表(3) Camera開發(7) CameraAPI1(4) CameraAPI2(2) CustomSDK(3) Kotlin版(23) JNI(6) 初階(4) 專案(2) 進階(11) CameraX(3) Mapbox_kotlin(4) ASP.NET(3) C/C++(23) APCS(7) 105_10(2) 106_03(3) 106_10(2) C++初階(6) C++進階(4) C++物件導向(4) ffmpeg(4) GPIO控制(12) Java(71) JavaAPI(7) JAVAMISC(3) JavaThread(7) Java基礎(7) Java物件導向(11) Java視窗設計(3) Java資料庫(2) Java進階(5) OCP國際認証(20) OCA803Exams(4) OCA808Exams(4) OCP804Exams(10) 大型專案技巧(4) 電算機概論(2) Kotlin(24) Kotlin基楚(6) kotlin進階(11) 視窗設計(4) PHP(8) Python(187) AI人工智慧(36) OpneCV(9) TensorFlow2(12) YOLO(3) 人臉辨識(1) 機器學習(4) Django(8) MTA(7) PyQt5視窗設計(15) PythonIO(4) Python函數(6) Python基礎(26) Python基礎程式(12) Python進階程式(14) Python物件導向(14) python專案(4) WebCam(4) wxPython視窗設計(14) 例外處理(2) 其他(3) 多工(5) 常用內建模組(3) 爬蟲程式(20) 資料分析(12) 資料視覺化(13) VisualC#(75) C#MSSQL(3) C#MySQL(1) C#OpenGL(2) C#列印(4) C#初階(17) C#物件導向(6) C#進階(8) C#高階(5) OpenCV(3) SerialPort(1) WPF(20) WPFChart(1) WPFResource(2) WPFUI(3) 數學(6) 未分類(6) 樹莓派(14) 雜記(15) NikonP1000(4) 中藥(3) 八字(3) 雲端架設(65) Git(6) AndroidGIT(1) GitTutorial(4) VSGit(1) JSP(3) Ubuntu(21) VMWare(3) WAMP(3) 網路概論(4) 資料庫(18) MSSQL(4) MySQL(13) 站務管理 登入 訂閱網站內容的資訊提供 訂閱留言的資訊提供 WordPress.org台灣繁體中文



請為這篇文章評分?