PCA.inverse_transform()の動作
PCA.transform()は主成分(分散の大きな軸)を見つけてそれを主軸とするような変換を行います。変換された値に対してPCA.inverse_transform()を行うと、元の変換される前の値を返します。
例として2次元平面上での理想的な楕円をPCA.transform()を行うとどうなるか、そしてさらに変換された値にPCA.inverse_transform()を行うとどうなるかを示します。
python
1import numpy as np
2import matplotlib.pyplot as plt
3from sklearn.decomposition import PCA
4
5
6def make_ellipse(a, b, theta):
7 rad = np.radians(theta)
8 c = np.cos(rad)
9 s = np.sin(rad)
10 r = np.array([[c, -s], [s, c]])
11 data = np.empty(shape=(360, 2))
12 for deg in range(0, 360, 1):
13 rad = np.radians(deg)
14 pos = np.array([a * np.cos(rad), b * np.sin(rad)])
15 data[deg, :] = r @ pos
16 return data
17
18
19def main():
20 X0 = make_ellipse(1.0, 0.5, 30)
21 pca = PCA(n_components=2)
22 pca.fit(X0)
23 X1 = pca.transform(X0)
24 X2 = pca.inverse_transform(X1)
25 X = np.array([X0, X1, X2])
26
27 fig, ax = plt.subplots(1, 3, figsize=(12, 4), sharey=True)
28 for i in range(3):
29 ax[i].plot(X[i, :, 0], X[i, :, 1])
30 ax[i].set_xlim(-1.5, 1.5)
31 ax[i].set_ylim(-1.5, 1.5)
32 ax[0].set_title("X0: Original")
33 ax[1].set_title("X1: pca.transform(X0)")
34 ax[2].set_title("X2: pca.inverse_transeform(X1)")
35 plt.show()
36
37
38if __name__ == "__main__":
39 main()
低次元から高次元へ戻る仕組み
簡単に言うと、N個のデータ、M個の特徴量に対してP次元のPCAを適用した場合
(N x P) = (N x M) (M x P) # (変換後) = (変換前) (変換行列)
となっています。変換行列(M x P)を覚えておいて、inverse_transform()する際には
(N x M) = (N x P) (P x M) # (変換前) = (変換後) (変換行列の転置行列)
を行っているだけです。
ソースコードの方を参照されているので詳しく説明します。入力データX0のデータ数をN, 特徴量の数をMとすると
python
1X0.shape == (N, M)
です。これにPCAの要素数をPとすると、pca.transform()後のX1は
python
1X1.shape == (N, P)
となります。このときPCAの内部ではfit()時に各々分散を計算して大きい順にP個保持しています。
python
1explained_variance_.shape == (P, ) # 1次元配列
np.newaxisは次元を1つ追加しますので
python
1explained_variance_[:, np.newaxis].shape == (P, 1)
と2次元配列になります。要素数P個は変わりません。
また主成分の係数components_
は
python
1components_.shape == (P, M)
になっています。この2つを掛け算すると
python
1(explained_variance_[:, np.newaxis] * components_).shape == (P, M)
となります。これはP個の分散の値をcomponents_の各行に掛け算しています。
np.sqrt()は次元を変えませんので、最終的に
np.dot(X, np.sqrt(self.explained_variance_[:, np.newaxis])
を計算することができます。Xは次元が減ったX1.shape == (N, P)のことですので、内積は(N, P) . (P, M) となり、演算結果の行列は(N, M)となります。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2020/07/20 00:27