teratail header banner
teratail header banner
質問するログイン新規登録

回答編集履歴

5

typoの修正

2020/07/19 22:02

投稿

yymmt
yymmt

スコア1615

answer CHANGED
@@ -74,7 +74,7 @@
74
74
  ```
75
75
  np.newaxisは次元を1つ追加しますので
76
76
  ```python
77
- explained_variance_[:, np.newaxis] == (P, 1)
77
+ explained_variance_[:, np.newaxis].shape == (P, 1)
78
78
  ```
79
79
  と2次元配列になります。要素数P個は変わりません。
80
80
 

4

質問に答えていなかったため追記

2020/07/19 22:02

投稿

yymmt
yymmt

スコア1615

answer CHANGED
@@ -1,3 +1,5 @@
1
+ #### PCA.inverse_transform()の動作
2
+
1
3
  PCA.transform()は主成分(分散の大きな軸)を見つけてそれを主軸とするような変換を行います。変換された値に対してPCA.inverse_transform()を行うと、元の変換される前の値を返します。
2
4
 
3
5
  例として2次元平面上での理想的な楕円をPCA.transform()を行うとどうなるか、そしてさらに変換された値にPCA.inverse_transform()を行うとどうなるかを示します。
@@ -44,4 +46,49 @@
44
46
  main()
45
47
  ```
46
48
 
47
- ![PCA.inverse_transform()の実験](98ed48234adbfa4ab26743d3bb802827.png)
49
+ ![PCA.inverse_transform()の実験](98ed48234adbfa4ab26743d3bb802827.png)
50
+
51
+ #### 低次元から高次元へ戻る仕組み
52
+
53
+ 簡単に言うと、N個のデータ、M個の特徴量に対してP次元のPCAを適用した場合
54
+
55
+ (N x P) = (N x M) (M x P) # (変換後) = (変換前) (変換行列)
56
+
57
+ となっています。変換行列(M x P)を覚えておいて、inverse_transform()する際には
58
+
59
+ (N x M) = (N x P) (P x M) # (変換前) = (変換後) (変換行列の転置行列)
60
+
61
+ を行っているだけです。
62
+
63
+ ソースコードの方を参照されているので詳しく説明します。入力データX0のデータ数をN, 特徴量の数をMとすると
64
+ ```python
65
+ X0.shape == (N, M)
66
+ ```
67
+ です。これにPCAの要素数をPとすると、pca.transform()後のX1は
68
+ ```python
69
+ X1.shape == (N, P)
70
+ ```
71
+ となります。このときPCAの内部ではfit()時に各々分散を計算して大きい順にP個保持しています。
72
+ ```python
73
+ explained_variance_.shape == (P, ) # 1次元配列
74
+ ```
75
+ np.newaxisは次元を1つ追加しますので
76
+ ```python
77
+ explained_variance_[:, np.newaxis] == (P, 1)
78
+ ```
79
+ と2次元配列になります。要素数P個は変わりません。
80
+
81
+ また主成分の係数`components_`は
82
+ ```python
83
+ components_.shape == (P, M)
84
+ ```
85
+ になっています。この2つを掛け算すると
86
+ ```python
87
+ (explained_variance_[:, np.newaxis] * components_).shape == (P, M)
88
+ ```
89
+ となります。これはP個の分散の値をcomponents_の各行に掛け算しています。
90
+ np.sqrt()は次元を変えませんので、最終的に
91
+ ```
92
+ np.dot(X, np.sqrt(self.explained_variance_[:, np.newaxis])
93
+ ```
94
+ を計算することができます。Xは次元が減ったX1.shape == (N, P)のことですので、内積は(N, P) . (P, M) となり、演算結果の行列は(N, M)となります。

3

typoの修正

2020/07/19 21:57

投稿

yymmt
yymmt

スコア1615

answer CHANGED
@@ -1,4 +1,4 @@
1
- PCA.transform()は主成分(分散の大きな軸)を見つけてそれを主軸とするような変換を行います。変換された値に対してPCA.inverse_transform()を行うと、元の回転される前の値を返します。
1
+ PCA.transform()は主成分(分散の大きな軸)を見つけてそれを主軸とするような変換を行います。変換された値に対してPCA.inverse_transform()を行うと、元の変換される前の値を返します。
2
2
 
3
3
  例として2次元平面上での理想的な楕円をPCA.transform()を行うとどうなるか、そしてさらに変換された値にPCA.inverse_transform()を行うとどうなるかを示します。
4
4
 

2

回転とも少し違う、どちらかと言えば投影のが近い

2020/07/19 17:41

投稿

yymmt
yymmt

スコア1615

answer CHANGED
@@ -1,4 +1,4 @@
1
- PCA.transform()は主成分(分散の大きな軸)を見つけて軸を回転した値を返します。回転された値に対してPCA.inverse_transform()を行うと、元の回転される前の値を返します。
1
+ PCA.transform()は主成分(分散の大きな軸)を見つけてそれを主とするような変換行います。変換された値に対してPCA.inverse_transform()を行うと、元の回転される前の値を返します。
2
2
 
3
3
  例として2次元平面上での理想的な楕円をPCA.transform()を行うとどうなるか、そしてさらに変換された値にPCA.inverse_transform()を行うとどうなるかを示します。
4
4
 

1

正規化ではなく回転に修正

2020/07/19 17:40

投稿

yymmt
yymmt

スコア1615

answer CHANGED
@@ -1,4 +1,4 @@
1
- PCA.transform()は主成分(分散の大きな軸)を見つけて正規化された値を返します。正規化された値に対してPCA.inverse_transform()を行うと、元の正規化される前の値を返します。
1
+ PCA.transform()は主成分(分散の大きな軸)を見つけて軸を回転した値を返します。回転された値に対してPCA.inverse_transform()を行うと、元の回転される前の値を返します。
2
2
 
3
3
  例として2次元平面上での理想的な楕円をPCA.transform()を行うとどうなるか、そしてさらに変換された値にPCA.inverse_transform()を行うとどうなるかを示します。
4
4