はじめに
液晶画面に数百万画素で写された山の映像が目に入る途端に、脳が3次元の山にイメージするので、つまり多次元(数百万画素)のデータを主成分の3次元に削減(圧縮)すると考えられる。PCA(Principle Component Analysis)主成分分析は最も広く使用されている次元を削減するアルゴリズムで、\(n\)次元の特徴を\(m\)次元にマッピングすることである。主成分とも呼ばれるのは元のn次元の特徴から再構築された\(m\)次元の特徴である。そのうち最初の新しい座標軸の選択は元のデータで最大の分散を持つ方向であり、2番目の新しい座標軸の選択はこの座標軸における分散を最大化してかつ最初の座標軸と直交する座標軸であり、3番目の座標軸の選択はこの座標軸における分散を最大化してかつこれまで2つの軸と直交する座標軸であり、類推によってこのような座標軸を\(n\)個取得できる。殆どの分散が最初の軸\(m\)個に含まれて、後続の軸が騒音や相関などによりこれらの分散はゼロに近いことがわかる。従って残りの軸\((n-m)\)個を無視して最初の軸\(m\)個のみを残すと\(n\)次元の特徴をもつデータを\(m\)次元特徴空間に変換する。これで次元削減処理を実現することに相当する。
手順
・データの標準化、つまりデータからその特徴の平均値を差し引く
・共分散行列を計算
・共分散行列の固有値と固有ベクトルを計算
・固有値を大→小にソート
・最大の特徴ベクトルを保持
・データを特徴ベクトルによって構築された新しい空間に変換
実装
2次元のデータ6組\((-1, 1), (-2, -1), (-3, -2), (1, 1), (2, 1), (3, 2)\)の主成分を求める。
# Python PCA import numpy as np def pca(X,k):#k is remained components # Calculate mean of each feature n_samples, n_features = X.shape mean=np.array([np.mean(X[:,i]) for i in range(n_features)]) # Calculate normalization norm_X = X - mean # Calculate cov matrix cov_matrix = np.dot(np.transpose(norm_X), norm_X) # Calculate eigen vectors and eigen values eig_val, eig_vec = np.linalg.eig(cov_matrix) eig_pairs = [(np.abs(eig_val[i]), eig_vec[:,i]) for i in range(n_features)] # Sort eig_vec based on eig_val from big to small eig_pairs.sort(reverse=True) # Select the top k eig_vec feature = np.array([ele[1] for ele in eig_pairs[:k]]) # Get new data data = np.dot(norm_X, np.transpose(feature)) return data X = np.array([[-1, 1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]]) print(pca(X,1))
ソースコード
https://github.com/soarbear/Machine_Learning/tree/master/pca
結果
[[-0.50917706] [-2.40151069] [-3.7751606 ] [ 1.20075534] [ 2.05572155] [ 3.42937146]]
以下はsklearnを用いる例で、ソースは短くなるが結果の符号が逆になる。
# PCA with sklearn from sklearn.decomposition import PCA import numpy as np X = np.array([[-1, 1], [-2, -1], [-3, -2], [1, 1], [2, 1], [3, 2]]) pca=PCA(n_components=1) pca.fit(X) print(pca.transform(X))
参考文献
[1] PeterHarrington. Machine Learning in Action.