Scikit-learnのPCAの正しい使い方

先日、PCAとkmeansを使った分析の話を書いたが、ハマったところがあったので、書いておく。

ハマったところ

やりたいことは、実数空間を、別の軸ではられる空間に射影することだった。

従って、射影ベクトルは入力次元と同じだけ必要となる。

が、なんどやっても、入力次元よりも小さくなってしまう。

例えば、入力次元が7次元だったら、なぜか5次元になってしまう。

なんでや!

それ、間違ったメソッド使ってるで

多くのブログやページを見ると、

「PCAインスタンスを生成して、データをfitメソッドで入力して、transformメソッドで、入力データを射影するんやで」みたいなことが書いてある。

と、あるもんだから、

pca = PCA(n_components=dimention)

で射影先の次元数を指定して、

pca.fit(dataset)

でデータに適応させて、

dataset_low_dm = pca.transform(dataset)

とすれば、n_componentsで指定した次元数になるのかと思っていた。

が、公式マニュアルをよく見ていただきたい。

公式マニュアルのtransformメソッドの説明にはこう書いてある。

 Apply the dimensionality reduction on X.
 X is projected on the first principal components previous extracted from a training set.

もう一度、言おう。

X is projected on the first principal components ........(´・ω・`)

つまり、transformメソッドは第一主成分「だけの」の空間に射影する。

それだけのメソッドに過ぎなかったというわけだ。

では、どうしたらいいのか?

ここでやりたいことは、同じ次元数の別の空間に飛ばすことである。

要は、元の行列に写像行列をかけて、行列積をもとめてやればいいのだ。

じゃあ、写像行列はなんなのか?という話になる。

主成分分析において、主成分(よく第一主成分から順にPC1,PC2とか表されるやつ)は、共分散行列のことである。

第一主成分を取ってくるときは、共分散行列からスコアを出して、一番スコアが高いやつ〜と選んでいるにすぎない。

ここでは共分散行列をぜんぶ使って、写像行列とする。

で、scikit-learnで共分散行列を得るには

インスタンス.get_covariance()

でおk。

このメソッドの戻り値は、numpy.adarray型の共分散行列である。

あとは、dot(元の行列, 共分散行列)で別の空間への射影ができる。

教訓

公式マニュアルもきちんと読みましょう。


追記 9/3

写像行列は共分散行列である。という、なんともマヌケなことを書いてしまった。

そんなわけあるか。

この場合、写像行列は固有ベクトルから構成される行列になる。

このあたり、理解がいい加減だったので、別の記事にまとめた