LoginSignup
6
12

More than 3 years have passed since last update.

【機械学習】Kernel PCA を勉強してみる

Last updated at Posted at 2020-02-10

PCA

Kernel PCAの説明に入る前にPCAとは何か、ざっとおさらいしたいと思います。

PCAとは?

PCA(Principle Component Analysis)/主成分分析は、機械学習で主にデータの次元を減らすのに使われるテクニックです。「次元の呪い」としても知られるよう、特徴量が多すぎると学習に支障をきたします。なので、「不必要な特徴量はなるべく取り除きたい。本当に必要な特徴量だけを使いたい」のです。

PCAのメカニズム

各$x_i$がD次元(D個の特徴量)ベクトルのデータセットがあるとします。これをM次元に写すのに、y = Ax となる $A = [u_1^{T}, ... u_M^{T}]$、$u_k^{T}u_k = 1, k = 1,2... M$ があるとします。この時、PCAでは$y_i$の分散が最大になるAをみつけます。

A^* = argmax tr(S_y)
S_y=\dfrac {1}{N}\sum ^{N}_{i=1}\left( y_{i}-\overline {y}\right) \left( y_{i}-\overline {y}\right) ^{T}
\overline {y} = \dfrac {1}{N}\sum ^{N}_{i=1}x_i

$S_x$をSの分散共分散行列とした時、$tr(S_y) = tr(AS_xA^T)$により、ラグランジ定数を使い微分すると、下のような固有値ベクトル $u_k$による式になります。


S_xu_k = \lambda_ku_k

このように、PCAではxの分散が最大になるような固有値をとることで、特徴量を絞り出すことができます。
この固有値ベクトルによる写像は、下のような回転写像になります。
縦と横の広がりである、それぞれの特徴量の分散だけが残ったことがわかります。

Screenshot 2020-02-10 at 23.00.33.png

Kernel PCA

上記のPCAでは、線形分離できるデータに対して次元削除を行いましたが、データが線形分離できない時に Kernel PCAを使います。
D次元の特徴量をもつデータをM次元に写す$\phi (x)$があるとします。この時、スタンダードなPCAを新たな次元空間で行うこともできますが、大変なので、カーネルトリックを使います。
まず、写像後の特徴量は平均0をとると仮定します。

\dfrac {1}{N}\sum ^{N}_{i=1} \phi(x_i) = 0

この時、分散共分散は

C = \dfrac {1}{N}\sum ^{N}_{i=1} \phi(x_i)\phi(x_i)^T

となります。
固有値ベクトル$v_i$は、下の式から求めることができます。

Cv_k = \lambda_k v_k      

例えば、下のように、左のデータでは線形分離できませんが、カーネルを使うことで、線形分離可能になります。

Screenshot 2020-02-11 at 0.37.19.png

scikit learn Kernel PCA

パラメター 概要 選択肢 デフォルト
n_components ターゲットの次元数 int None(そのまま)
kernel カーネルタイプ “linear” ,“poly” , “rbf” ,“sigmoid” ,“cosine” "linear"
gamma rbfとpolyのカーネル係数 float 1/n_features
degree polyの係数 int 3
coef0 polyとsigmoidの独立係数 float 1
kernel_params カーネルのパラメターの名前 Stringからのmapping None
alpha リッジ回帰 1.0
eigen_solver 固有値の選択 "auto", "dense", "arpack" "auto"
tol arpackの収束 float 0
max_iter arpackの最大反復回数 int None
remove_zeros 固有値0の削除 bool False
random_state arpackでのrandom_state RandomState Instance or None None
n_jobs 並列作業 int/None None

使用例


import numpy as np
import matplotlib.pyplot as plt
from sklearn.decomposition import PCA, KernelPCA
from sklearn.datasets import make_circles
np.random.seed(0)
X, y = make_circles(n_samples=400, factor=.3, noise=.05)
plt.figure(figsize=(10,10))
plt.subplot(2, 2, 1, aspect='equal')
plt.title("Original space")
reds = y == 0
blues = y == 1
plt.scatter(X[reds, 0], X[reds, 1], c="red",s=20, edgecolor='k')
plt.scatter(X[blues, 0], X[blues, 1], c="blue",s=20, edgecolor='k')
plt.xlabel("$x_1$")
plt.ylabel("$x_2$")

download.png

-> 線形分裂できない。。。
RBFカーネル!

kpca = KernelPCA(kernel="rbf", fit_inverse_transform=True, gamma=10)
X_kpca = kpca.fit_transform(X)
pca = PCA()
X_pca = pca.fit_transform(X)
plt.scatter(X_kpca[reds, 0], X_kpca[reds, 1], c="red",s=20, edgecolor="k")
plt.scatter(X_kpca[blues, 0], X_kpca[blues, 1], c="blue",s=20, edgecolor="k")
x = np.linspace(-1, 1, 1000)
plt.plot(x, -0.1*x, linestyle="solid")
plt.title("Projection by KPCA")
plt.xlabel(r"1st PC induced by $\phi$")
plt.ylabel("2nd component")


分割後:

download (1).png

PCAの利点と欠点

利点

  • 特徴量間の関係を無視できる。
  • 学習がシンプルで速くなる。
  • 過学習を防ぐ。
  • より理解しやすい可視化。

欠点

  • 元々の特徴量の解釈が難しくなる。
  • 正規化が必要。

引用

Quan Wang, "Kernel Principal Component Analysis and its Applications in Face Recognition and Active Shape Models", 2014
https://arxiv.org/pdf/1207.3538.pdf

6
12
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
6
12