PRML 12章 カーネル主成分分析を R で実装(棒読み)

月曜日はPCA火曜日は確率的PCA水曜日はPCA with EMアルゴリズム木曜日はベイズPCA、と続いてきた「日刊☆主成分解析」も今日で最終回。
いよいよカーネル主成分分析(kernel PCA)。


カーネル PCA は非線形な特徴ベクトルで特徴空間にデータを移したところで主成分分析を行うもの。元のデータ空間では非線形な主成分解析モデルを考えていることに相当する。
以下がカーネル成分解析を行う R のコード。

library(kernlab)
oilflow <- read.table("DataTrn.txt");
result <- kpca(oilflow)    # Rならカーネル主成分分析が1行で書ける!!!

oilflow.labels <- read.table("DataTrnLbls.txt");
col <- colSums(t(oilflow.labels) * c(4,3,2));  # ラベルごとに色を指定
pch <- colSums(t(oilflow.labels) * c(3,1,4));  # ラベルごとにマーカーを指定
plot(pcv(result), col=col, pch=pch)


最後の最後でまたやっちゃいましたね!
oil flow データセットはデータ集合の大きさが N=1000 なので、1000x1000 のグラム行列とかなんか作ってみて遅かったらやだなあ、カーネル主成分分析のモジュールくらいあるよね? と日和りました。ごめんなさい。
確率的でもない、繰り返しもないアルゴリズムってあんまり実装して楽しくないもんで……
それに、どちらかというとカーネル主成分分析では自分で実装してみることより、カーネル関数を変えたときに結果がどのように変わるのかというあたりの方が興味あったので。


簡単に kernlab パッケージの使い方。
インストールは CRAN から取ってくるだけ。
kpca() がカーネル PCA の関数。

kpca(
	x = [データ(行列またはデータフレーム)], 
	kernel = [カーネル関数], 
	kpar = [カーネル関数のパラメータを list() で指定],
	features = [特徴空間の次元。0(デフォルト)にするとグラム行列のrankから勝手に決まる……のかな?]
);

帰ってきた結果を pcv() に食わせると、データ点を特徴空間に射影した座標が得られるので、それを使って散布図を描く。


kpar はデフォルトで sigma=0.1 が指定されている。
線形カーネルなどパラメータを必要としないカーネルの場合だとわざわざ空の list() を指定しないとエラーになってしまう。どちらかというと迷惑。


kernel に指定するカーネル関数は rbfdot(ガウシアンカーネル:デフォルト)、vanilladot(線形カーネル)、polydot(多項式カーネル)、tanhdot(ハイパボリックタンジェントカーネル)、などなど。詳しくは kernlab のリファレンスの "dots" の項に提供されているカーネル関数の一覧があるから、そこを見てね。
kernlab パッケージでは、他にも SVM とかカーネル正準相関分析とかもできるっぽいが、今回は試していない。


というわけでいろいろなカーネル関数やパラメータで描いてみた。

線形カーネル


まずはこれ。
通常の PCA はカーネル PCA において線形カーネルを使った特別な場合として再現できる、と PRML にも書かれていたとおり。

ガウスカーネル

ガウシアンカーネル(σ=1)

ガウシアンカーネル(σ=0.1)

ガウシアンカーネル(σ=0.001)

一番ポピュラー(ですよね?)な Gaussian カーネル
kernlab のマニュアルを見ると PRML とは定義が違っていて、σは "inverse kernel width" となっている(つまり PRML の定義の逆)。
σだと標準偏差→幅を想起させられるので、PRML の定義の方が自然に感じるんだがなあ。


ともあれ。
σが大きいと予測しにくい形に。ちなみにσ=10 とかすると、青と緑はほぼ一点に固まり、赤が散らばっているという散布図が出てくる。
σを小さくすると線形カーネル(つまり通常の PCA)の結果に近づいている?

多項式カーネル

多項式カーネル(2次)

多項式カーネル(3次)

多項式カーネルの1次は定義から明らかに線形カーネルなので、2次と3次を載せてみた。

tanh カーネル

ハイパボリックタンジェントカーネル(offset=1)

オフセット変えてみたけど、散布図の変化はとても小さかったので、1枚だけ。

ANOVA RBF カーネル&スプラインカーネル

ANOVA RBF カーネル(σ=1, degree=1)

ANOVA RBF カーネル(σ=0.1, degree=2)

スプラインカーネル(σ=1, degree=1)

結論?

カーネル PCA でカーネル関数は固定してパラメータだけをいじると、もちろん結果は変わっていくが、根本的な構造は大きく変化し無さそう。
「望ましい結果」を出すには、カーネル関数自体を問題にあわせて設定していくべきっぽいが、きっととても難しい。
データからカーネル関数を作る話は「カーネル多変量解析」の 3.2 にラプラシアン固有マップとか書いてあったが、やっぱり大変そうだ。
いろいろなカーネル関数で試行錯誤して、なにがしかの指標が一番いいものを採用、なんか思いがけずとびきり良い結果が出たらラッキー!! な感じなんだろうか……。