K_DM Book
用語集
対象者 標準
対象者別の入口 →

対象者の設定はこのブラウザの中にだけ保存されます。

言語 JA

Kernel-PCA

中級

02.7.4

Kernel-PCA

最終更新 2020-03-11 読了時間 3 分
まとめ
Kernel PCA は、データを非線形写像 \(\phi(x)\) で高次元の特徴空間に移してから PCA を行う手法で、元の空間では同心円や渦巻きのように曲がって見える構造を直線的に分けられる軸を取り出します。写像先の座標を実際に計算する代わりに、点同士の内積をカーネル関数 \(k(x_i, x_j)\) で直接求めたカーネル行列 \(K\) を固有値分解するので、計算は \(n \times n\) 行列の固有値問題に収まります。どの構造を分けられるかはカーネルの種類と gamma のようなパラメータで決まり、RBF カーネルの gamma=3 なら make_circles の内側と外側の円が第 1 主成分の正負で分かれます。線形 PCA では表現できない曲線的な構造の圧縮・可視化に向きますが、カーネル行列が \(O(n^2)\) なので数万点を超えると重くなります。

直感 #

同心円に並んだ 2 クラスの点を、1 本の直線で分けることはできません。しかし「原点からの距離」を新しい座標として足せば、内側の円は距離 0.3、外側の円は距離 1.0 の 2 本の線に分かれ、1 本の直線で切れます。Kernel PCA はこの「見え方の座標系を変える」操作を、RBF カーネル \(\exp(-\gamma |x - x’|^2)\) のような関数で自動的に行います。元空間で曲がって見える構造を、カーネルが定める高次元空間で直線的に扱い、そこで分散が最大の軸を取るのが本質です。gamma はカーネルの「視野の広さ」で、大きいほど近い点だけが似ていると判定されます。

何が起きているか(ステップで見る) #

コードを読む前に、この手法が図の上で何をしているかを追ってみましょう。「再生」を押すか、スライダーを動かすと 1 手順ずつ進みます。

見るポイント:点を軸に射影した散らばりが最大の向きが第 1 主成分。情報を最も失わない 1 本の軸。Kernel PCA はこの射影を、カーネルで写した高次元空間の中で行う。

詳細な解説 #


1. 直感:非線形構造を扱うPCA #

PCA は「分散が最大の方向」を探しますが、軸を回転させるだけなので直線的な構造しか表現できません。「円」や「渦巻き」では、軸を回しても 2 つの円は重なったままです。Kernel PCA はデータを高次元空間に写像してから PCA を適用し、写像先で直線的に分かれる軸を探します。


2. 数式でみる Kernel PCA #

データ点 \(x_i \in \mathbb{R}^d\) を非線形写像 \(\phi(x)\) によって高次元空間へ移します。写像先の座標 \(\phi(x)\) は使わず、内積だけを使うのが要点です。

まずカーネル行列を作ります。\(K_{ij}\) は写像先での点 \(i\) と \(j\) の内積で、カーネル関数 \(k(x_i, x_j)\) を直接計算することで、高次元空間に行かずに内積が得られます。

$$ K_{ij} = \langle \phi(x_i), \phi(x_j) \rangle $$

次に、この \(n \times n\) 行列の固有値問題を解きます。固有ベクトル \(v\) が写像先での主成分方向に対応し、固有値 \(\lambda\) がその方向の分散です。固有値の大きい順に n_components 個を取ると、非線形構造に対応した主成分が得られます。

$$ K v = \lambda v $$

代表的なカーネル関数は 2 つあります。RBF カーネル(ガウシアン)は距離が 0 なら 1、離れると 0 に近づく関数で、\(\gamma\) が減衰の速さです。

$$ k(x, x') = \exp(-\gamma \|x - x'\|^2) $$

多項式カーネルは内積の \(d\) 乗で、\(d=2\) なら元の特徴量の 2 次の組み合わせを暗に使うことになります。

$$ k(x, x') = (\langle x, x' \rangle + c)^d $$

3. 実験用データ(円環構造) #

make_circles で内側と外側の 2 つの円からなる 400 点を作り、クラスを色にして描きます。線形 PCA では分けられない形です。

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
import numpy as np
import matplotlib.pyplot as plt
from sklearn.datasets import make_circles

X, y = make_circles(n_samples=400, factor=0.3, noise=0.15)

plt.figure(figsize=(8, 8))
plt.scatter(X[:, 0], X[:, 1], c=y)
plt.title("円環状データ")
plt.show()

実験用データ(円環構造)の図


4. Kernel PCAで次元削減 #

KernelPCA(kernel="rbf", gamma=3) で変換し、第 1・第 2 主成分の平面に同じ色で描き直します。

1
2
3
4
5
6
7
8
9
from sklearn.decomposition import KernelPCA

kpca = KernelPCA(kernel="rbf", gamma=3)
X_kpca = kpca.fit_transform(X)

plt.figure(figsize=(8, 8))
plt.scatter(X_kpca[:, 0], X_kpca[:, 1], c=y)
plt.title("Kernel PCAによる2次元化")
plt.show()

Kernel PCAで次元削減の図

通常のPCAでは分離できなかった「同心円のクラス」が、Kernel PCAではきれいに分離できる。

実行結果の読み方 #

変換後の図では、元は同心円だった 2 クラスが第 1 主成分の正側と負側に分かれ、縦方向(第 2 主成分)には円の角度に応じて広がります。この平面にロジスティック回帰や線形 SVM をかければ、元空間では不可能だった直線での分類ができます。


5. 実務での応用 #

Kernel PCA の主な使い道は 3 つです。1 つ目は円形・渦巻きのような非線形構造の可視化で、線形 PCA で重なる塊が分かれるかを確認します。2 つ目はパターン認識で、手書き文字や顔画像の特徴抽出に使われてきました。3 つ目は非線形分類の前処理で、Kernel PCA で変換した座標を線形 SVM やロジスティック回帰に渡すと、カーネル SVM に近い性能を線形モデルで得られます。


発展:Kernel PCAの注意点 #

最初の注意点はカーネル選択で、RBF の gamma や多項式の次数 d が合わないと構造が出ません。gamma はデータの距離スケールに依存するので、StandardScaler で列をそろえた上で 0.1〜50 の範囲を対数的に試します。二つ目は計算コストで、カーネル行列は \(O(n^2)\) のメモリと \(O(n^3)\) の固有値分解を要し、1 万点で 800 MB 前後になります。三つ目は固有値の解釈で、通常の PCA の「寄与率」のように「元の特徴量の分散の何 % を保ったか」とは読めず、inverse_transform で元空間に戻すにも近似(fit_inverse_transform=True)が必要です。


  • 主成分分析(PCA) — 線形版の基本手法
  • t-SNE — 近傍の確率分布を保つ可視化向けの非線形手法
  • Isomap — 多様体学習の別手法
  • UMAP — 近傍グラフに基づく高速な非線形の次元削減手法

γ と Kernel PCA #

スライダーで RBF カーネルの gamma を 0.1, 0.5, 1, 5, 10, 50 と変えると、2 クラスの埋め込みがどう変わるかを確認できます。0.1 ではカーネルがほぼ線形で元の円の形が残り、1〜5 で 2 クラスが第 1 主成分の正負に分かれ、50 では各点が自分自身としか似ていなくなって塊が崩れます。