質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

6706閲覧

PCAのinverse_transformは何をしているのかが知りたい

ttt_

総合スコア6

データ構造

データ構造とは、データの集まりをコンピュータの中で効果的に扱うために、一定の形式に系統立てて格納する形式を指します。(配列/連想配列/木構造など)

関数

関数(ファンクション・メソッド・サブルーチンとも呼ばれる)は、はプログラムのコードの一部であり、ある特定のタスクを処理するように設計されたものです。

機械学習

機械学習は、データからパターンを自動的に発見し、そこから知能的な判断を下すためのコンピューターアルゴリズムを指します。人工知能における課題のひとつです。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2020/07/19 07:50

編集2020/07/19 11:29

pythonでPCAを学んでいますが、inverse_transform関数で何を行っているのかが分からず質問しました。

下記のようにinverse_transform関数を使うと、2次元に削減したデータが元の3次元に戻ります。

次元が同じだけでデータの値は元の数値と異なりますが、この関数では元のデータに戻す関数なのでしょうか。
仮に元ののデータを推測して戻しているのだとしたらどのように戻しているのでしょうか。
PCAのinspect.getsource関数で中を見てみましたが、分かりませんでした。

分かる方がいたら教えてください。
宜しくお願いします。

python

1import numpy as np 2from sklearn.decomposition import PCA 3 4df = np.random.randn(6, 3) 5 6pca = PCA(n_components=2) 7pca.fit(df) 8feature = pca.transform(df) 9pca.inverse_transform(feature)

python

1from sklearn.decomposition import PCA 2import inspect 3print(inspect.getsource(PCA))

追記
下記のコードで関数の中身が見れらしたが、self.whitenが何を指しているのかが分かりませんでした。
whiten : bool, optional (default False)
When True (False by default) the components_ vectors are multiplied
by the square root of n_samples and then divided by the singular values
to ensure uncorrelated outputs with unit component-wise variances.

python

1import inspect 2inspect.getsource(PCA.inverse_transform)

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

guest

回答1

0

ベストアンサー

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()

PCA.inverse_transform()の実験

低次元から高次元へ戻る仕組み

簡単に言うと、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/19 17:36

編集2020/07/19 22:02
yymmt

総合スコア1615

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

ttt_

2020/07/20 00:27

大変詳しく説明してくださりありがとうございます。 inverse_transform()についてよくわかりました。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問