下校時刻

メモ、読んだ本のまとめメモ、考えたことのメモ、その他のメモなどが書いてあるブログです(twitter: @hoture6)

「Python Machine Learning」Ch. 5(次元削減について)まとめ

Ch. 5は次元削減の話です。この章はけっこう難しかったので簡単にまとめて、また興味や必要に応じて戻ってくることにしました。


次元の呪いを避けるために特徴量の数を減らす手法として、Ch. 4では特徴選択(有効な特徴量のみを使う)を考えたが、ここでは特徴量抽出(線形結合によりいい感じの特徴量を作る)を考える。主な手法は3つ。

  • PCA(Principal component analysis):教師なし
  • LDA(Linear descriminant analysis):教師あり
  • カーネルPCA:PCAの非線形ver.

PCA

データを軸上に射影した時の分散が一番大きくなるような軸をとる。この軸を1つ目の主成分とする。次に、この軸に対して直行する軸の中で、同様にデータの分散が大きくなる軸を2つ目の主成分とする。以上の手続きを何回か繰り返すというのがPCAの考え方である。これにより、互いに独立でかつ情報量の多い特徴量が得られる。

実際の計算においては、特徴量をすべて標準化してスケールを揃えた上で共分散行列を対角化する。固有値が大きい順に固有ベクトルを並び替え、好きな個数とってきたものが主成分となる。固有値の大きさを企画化した値

$$\frac{\lambda_{i}}{\sum_{j} \lambda_{j}}$$

が、対応する主成分の重要性を表すvariance explained ratioとなる。

scikit-learnでの実装は以下。

from sklearn.decomposition import PCA

pca = PCA(n_components-2) # 主成分の数
X_tr_pca = pca.fit_transform(X_tr_std)
X_ts_pca = pca.transform(X_ts_std) 

pca.explained_variance_ratio_ # variance explained ratioにアクセス

LDA

LDAの考え方はPCAと似ているが、教師ありであるという点が大きく異なる。PCAがデータの分散を大きくするように特徴量を作っていたのに対して、LDAでは正解ラベルも見た上でクラスの分割をしやすいように特徴量を作る。

LDAでは以下の仮定を設けている。

  • データは正規分布している
  • 特徴量同士は独立
  • 異なるクラスはすべて同じ共分散行列をもつ

一方で、上記の仮定が満たされていない場合でもLDAはけっこううまく動くことが知られている。

scikit-learnでの実装は以下。

from sklearn.lda import LDA

lda = LDA(n_components-2)
X_tr_lda = lda.fit_transform(X_tr_std, y_tr)
X_ts_lda = lda.transform(X_ts_std) 

カーネルPCA

非線形な問題については、PCAやLDAではなくカーネルPCAを使うことでうまく特徴量の抽出ができる。カーネルPCAの基本的な考え方は、いったん高次元空間にマップしてからPCAを行うというものである。

scikit-learnでの実装は以下。

from sklearn.decomposition import KernelPCA

kpca = KernelPCA(n_components-2, kernel='rbf', gamma=15)
X_tr_kpca = kpca.fit_transform(X_tr_std)
X_ts_kpca = kpca.transform(X_ts_std)