月曜日は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 とかカーネル正準相関分析とかもできるっぽいが、今回は試していない。
というわけでいろいろなカーネル関数やパラメータで描いてみた。
ガウスカーネル
ガウシアンカーネル(σ=1)
ガウシアンカーネル(σ=0.1)
ガウシアンカーネル(σ=0.001)
一番ポピュラー(ですよね?)な Gaussian カーネル。
kernlab のマニュアルを見ると PRML とは定義が違っていて、σは "inverse kernel width" となっている(つまり PRML の定義の逆)。
σだと標準偏差→幅を想起させられるので、PRML の定義の方が自然に感じるんだがなあ。
ともあれ。
σが大きいと予測しにくい形に。ちなみにσ=10 とかすると、青と緑はほぼ一点に固まり、赤が散らばっているという散布図が出てくる。
σを小さくすると線形カーネル(つまり通常の PCA)の結果に近づいている?