多維度資料視覺化呈現的好夥伴-主成份分析法(PCA)

主成份分析法(Principal components analysis, PCA) 是一種統計分析的方法,用於將多維度的資料集簡化為較低維度的資料。 本文使用 Python, SciKit Learn 將四維度的資料簡化為較易視覺化的二維度資料。


主成份分析法

主成份分析法簡單來說就是「哪個維度的資料對於整體資料分離度有較大的影響」。舉例來說如果要把隨機的一群人做分類,差異最大的資料可能是性別男或女,其次也許是膚色、眼瞳顏色、國籍,而較不重要的如髮色、體重等等,但如果今天取樣的人群是來自一同一個籃球隊,那麼性別資料將沒有任何意義,取而代之的可能是兩分球命中率等等數據,依照來源資料會有所不同

因此找出哪些資料對於此資料集較為重要、哪些相反,就是 PCA 的目的。


資料集

這次的 資料集 是使用我的大學專題,來自於用 Kinect 取得人體關節的座標點後,透過向量夾角計算方式來取得上半身手部的關節角度,包含:

  1. 左肩
  2. 左肘
  3. 右肩
  4. 右肘

當初專題報告時因為學藝不精,不知道四維的資料到底怎麼呈現,所以只好把左半部及右半部拆成下面兩張圖表來呈現,但是結果看來這樣的表現方法並沒有辦法讓人理解這些資料怎麼了

當時專題中把這些資料丟到了類神經網路中訓練,最後成果的辨識率卻只有82%,但是我並不知道到底是資料出了問題還是 模型的設計不良


使用 SciKit Learn 實作

講了這麼多以後終於來到了實作的部分了,SciKit Learn 是一個強大的 Python Library,其中包含了許多經典的機器學習演算法及資料集,如果對於這方面有興趣的絕對不能錯過。

from sklearn.decomposition import PCA
import numpy as np
import matplotlib.pyplot as plt

# 讀取資料集的部分跳過
x_data = np.array(x) # x 為四維的資料
y_data = np.array(y) # y 為此資料的類別

# 執行 PCA
pca = PCA(n_components=2) # n_components 為要降到的維度,這邊降為二維
pca.fit(x_data) # 使用 x_data 為來源資料
result = pca.transform(x_data) # 使用 transform() 即可取得降維後的陣列
print(result)
"""
[[  46.73366818  152.18796606]
 [  41.79258837  149.06218459]
 [  61.96240243  154.09447172]
 ...,
 [-155.36958291   55.70832811]
 [-155.96042941   45.55093678]
 [-161.31800221   42.75759598]]
"""

# components_ 為組成此 PCA 結果的各項係數
print(processed.components_)
"""
[[-0.3944201  -0.08305884  0.89110626  0.20847939]
 [ 0.86009346  0.29969379  0.36235102  0.19779942]]
"""

# 使用 matplotlib 將結果繪出
# 前兩個參數是各個點的 x,y 座標值
# c 是按照每筆資料的類別數值(1~9),自動著色
plt.scatter(result[:,0], result[:,1], c=y_data, s=25, alpha=0.4, marker='o')

按照了上面程式的流程後,我們就可以得到了下圖,老實說當初把這張圖畫出來以後,突然有種莫名的感動。透過了這張圖我才發現 其實整體資料集看起來還不錯的,所以事實證明當初訓練的模型並不好。

(後來改用 Keras 建立新模型後,辨識率最高達到了99.04%)


總結

我覺得當初大學很可惜的地方在於,系上沒有教授對於我所感興趣的機器學習、人工智慧這一塊有鑽研,做專題時指導教授也沒辦法指導什麼,甚至偶爾 meeting 時會覺得教授根本是在搗亂,專出完全不是重點的餿主意。這過程中是自己一點一點地去學習,才稍微的入門了。

而去年去參加了 2016資料科學年會 以後,才終於知道有許多種方法可以在過程中提供幫助,因此在此寫了一點小筆記,希望可以幫助到其他人。

(部分的程式有放在 GitHub 上)