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
写像行列は共分散行列である。という、なんともマヌケなことを書いてしまった。
そんなわけあるか。
このあたり、理解がいい加減だったので、別の記事にまとめた