はじめに
この記事ではPythonで主成分分析(PCA)の実装を行います。
まずはじめにscikit-learn
を用いて実装した後に、
NumPy
のみを利用して、自前での実装を試みます。
実装
scikit-learn
まずはscikit-learn
を使ってみます。
データにはフィッシャーのアヤメ
を用います
1 2 3 4 5 6 7 8 9 10 11 12
| from sklearn.datasets import load_iris import numpy as np iris = load_iris() X = iris.data from sklearn.decomposition import PCA pca = PCA() X_ = (X - X.mean(axis=0))/X.std(axis=0) X_new = pca.fit_transform(X_) print (pca.explained_variance_) print (pca.explained_variance_ratio_) print (pca.components_) print (X_new[0])
|
pca.explained_variance_ratio_
は、変換後の各主成分の寄与率を表しています。
pca.explained_variance_
やpca.components_
が何者なのかは今後わかります。
固有値分解
次に固有値分解を用いた実装を行います。
主成分分析は、データの分散共分散行列の固有値分解に帰着できます。確認してみましょう。
1 2 3 4 5 6 7 8 9 10 11
| class MyPCA: def __init__(self): pass def fit_transform_eig(self, X): X = (X - X.mean(axis=0))/X.std(axis=0) cov = np.cov(X.T) l, v = np.linalg.eig(cov) self.explained_variance_ = l self.explained_variance_ratio_ = self.explained_variance_ / self.explained_variance_.sum() self.components_ = v return X.dot(v)
|
1 2 3 4 5 6
| pca = MyPCA() X_new = pca.fit_transform_eig(X) print (pca.explained_variance_) print (pca.explained_variance_ratio_) print (pca.components_) print (X_new[0])
|
先ほどと全く同じ結果が得られたはずです。
さて、ここでpca.explained_variance_
が固有値に相当することが分かります。そして、その和が1になるように規格化したのがpca.explained_variance_ratio_
となります。
また、pca.components_
が固有ベクトルに相当することが分かります。
特異値分解
次に特異値分解を用いて実装することもできます。実際、scikit-learn
の主成分分析は特異値分解で実装されています。
これは対称行列の特異値と固有値が等しく、かつ分散共分散行列は対称行列であるためです。
1 2 3 4 5 6 7 8 9 10 11
| class MyPCA: def __init__(self): pass def fit_transform_svd(self, X): X = (X - X.mean(axis=0))/X.std(axis=0) cov = np.cov(X.T) U, s, V = np.linalg.svd(cov) self.explained_variance_ = s self.explained_variance_ratio_ = self.explained_variance_ / self.explained_variance_.sum() self.components_ = U return X.dot(V.T)
|
1 2 3 4 5 6
| pca = MyPCA() X_new = pca.fit_transform_svd(X) print (pca.explained_variance_) print (pca.explained_variance_ratio_) print (pca.components_) print (X_new[0])
|
分散共分散行列が対称行列であるため、固有値と特異値、固有ベクトルと特異ベクトルが等しくなっていることも確認できます。
まとめ
NumPy
の固有値分解や特異値分解を使って、scikit-learn
のPCA
を再現することができました。
記事情報
- 投稿日:2020年4月7日
- 最終更新日:2020年4月7日