Aidemy 2020/10/29
はじめに
こんにちは、んがょぺです!バリバリの文系ですが、AIの可能性に興味を持ったのがきっかけで、AI特化型スクール「Aidemy」に通い、勉強しています。ここで得られた知識を皆さんと共有したいと思い、Qiitaでまとめています。以前のまとめ記事も多くの方に読んでいただけてとても嬉しいです。ありがとうございます!
今回は、教師なし学習の3つ目の投稿になります。どうぞよろしくお願いします。
*本記事は「Aidemy」での学習内容を「自分の言葉で」まとめたものになります。表現の間違いや勘違いを含む可能性があります。ご了承ください。
今回学ぶこと
・主成分分析について
・カーネル主成分分析について
主成分分析
主成分分析について
・主成分分析は、少ないデータから元のデータを表すこと、すなわちデータの要約(圧縮)を行う手法の一つである。
・主成分分析を行うと、「全てのデータを効率よく説明できる軸(第一主成分軸)」と「それだけでは説明しきれないデータを効率よく説明できる軸(第二主成分軸)」が作成される。
・このうち第一主成分のみを使うことで、余分なデータを捨てられ、データが圧縮できる。
・主成分分析を使えば次元削減も行えるので、データを2、3次元に落として可視化させたり、回帰分析に使えるようにしたりできる。
主成分分析の流れ(概要)
①データXを標準化する。
②特徴同士の相関行列を計算する。
③相関行列の固有値と固有ベクトルを求める。
④固有値の大きい方からk個(k=圧縮したい次元数)選び、対応する固有ベクトルを選択する。
⑤選んだk個の固有ベクトルから特徴変換行列Wを作成する。
⑥データXと行列Wの積を計算し、k次元に変換されたデータX'を得る。(終了)
主成分分析① 標準化
・標準化とは、データの各特徴を、平均を0分散を1になるように変換することである。
・標準化を行うことで、単位や基準の異なるデータを同じように扱えるようになる。
・標準化は以下のように行われる。 (データと平均の差)÷標準偏差
X = (X - X.mean(axis=0))/X.std(axis=0)
主成分分析② 相関行列
・相関行列とは、各特徴データ同士の相関係数がk×k個集まった行列のことである。
相関係数は2データ間の直線的な関係性の強さを表し、1に近いほど「aが正の一次関数の傾向が強い」すなわち、正の相関が強いと言え、-1に近いほど「aが負の一次関数の傾向が強い」すなわち、負の相関が強いと言える。
・相関係数が0に近いときは、直線的な傾向があまりないことを示す。
・相関行列Rの計算は以下のように行われる。
R = np.corrcoef(X.T)
・相関行列を行うnp.corrcoef()に渡すのが、転置を行ったデータX.Tであるのは、Xのまま渡すとデータそのもの(行同士)の相関行列を計算してしまうためである。今回は「特徴データ(列同士)」の相関行列を計算したいので、このような場合は転置すれば良い。
主成分分析③ 固有値と固有ベクトル
・②で求めた相関行列Rは、固有値分解というものを行うと固有値と固有ベクトルに分解される。この二つはそれぞれ行列の次元数と同じ個数で分解される。
・固有ベクトルが示すのは、行列Rにおいてその方向に情報が集中していること、固有値はその集中の度合いを示す。
・固有値分解は以下のように取得できる。変数のeigvalsに固有値が、eigvecsに固有ベクトルが昇順で格納される。
eigvals, eigvecs = np.linalg.eigh(R)
主成分分析④⑤⑥ 特徴変換
・ここでは、データの次元を任意のk次元に変換する手順を見ていく。
・③で分解した固有値のうち大きいものからk個を使って変換する(④)。具体的には、このk個の固有値にそれぞれ対応する固有ベクトルを連結して特徴変換行列Wを作成する(⑤)。最後に、このWとデータXをかけることで、k次元に変換されたデータX'を取得することができる(⑥)。
・変換行列Wの作成方法は以下の通りである。(2次元に変換したい場合)
W = np.c_[eigvecs[:,-1],eigvecs[:,-2]]
・XとWの積は「行列積」なのでX.dot(W)で計算する。
主成分分析①〜⑥を簡単に行う
・以上①〜⑥の手順で主成分分析を行うことができるが、PCAというscikit-learnのクラスを使うことで簡単に主成分分析を行うことができる。
回帰分析の前処理としての主成分分析
・LogisticRegression()を使用した回帰分析を実行する前に、主成分分析を行ってデータを圧縮しておくことで、より汎用性の高いモデルを作ることができる。
・以下では、データを分割したX_trainとX_testについて、標準化と主成分分析を行う。標準化には「StandardScaler」クラス、主成分分析にはPCAクラスを使うと良い。また、トレーニングデータとテストデータは共通の基準で処理する。
・trainデータは学習させる必要があるので「fit_transform()」を使い、testデータはそのまま「transform()」を使えば良い。
カーネル主成分分析
カーネル主成分分析とは
・回帰分析などの機械学習は線形分離を前提としているため、線形分離不可能な
データは扱うことができないが、非線形分離のデータを線形可能なデータに変換するカーネル主成分分析(カーネルPCA)という物を使えば、そのようなデータも扱うことができるようになる。
・カーネルPCAでは、与えられたN(データ数)×M(特徴)のデータを、新しい特徴M'を持ったN×M'のデータKに作り替えるということを行う。これをカーネルトリックと言い、Kをカーネル行列という。
・このカーネル行列Kは主成分分析をすることが可能となる。
カーネルトリックについて
・カーネルトリックを行うには、まずカーネル行列Kを算出する必要がある。元のデータがN(データ数)×M(特徴)ならば、KはN×Nとなる。
・カーネル行列は「データのペアごとの類似度」を計算したカーネル関数を行列にした物である。
・このカーネル関数は数種類あるが、今回はその中の動径基底関数(カーネル)のガウスカーネルについて見ていく。
・カーネル関数の一つガウスカーネルは以下のようにして計算できる。
#データ同士の平方ユークリッド距離を計算
M = np.sum((X - X[:,np.newaxis])**2, axis=2)
#Mを使ってカーネル行列を計算
K = np.exp(-gamma*M)
カーネルトリックしたデータを主成分分析
・先述の通り、カーネルトリックを行って取得したカーネル行列Kは、主成分分析を行うことができる。
・主成分分析を行うことで、元は線形分離不可能だったデータXを、線形分離可能なデータX'に変換することができる。
カーネル主成分分析を簡単に行う
・KernelPCAというscikit-learnのクラスを使うことで簡単にカーネル主成分分析を行うことができる。
・引数については、n_componentsが圧縮後の次元数、kernelが動径基底関数(カーネル)、gammaがカーネル行列の算出に使われる「γ」の値を示す。
from sklearn.decomposition import KernelPCA
#KernelPCAインスタンスを作成し、主成分分析する
kpca = KernelPCA(n_components=2, kernel="rbf", gamma=15)
X_kpca = kpca.fit_transform(X)
まとめ
・主成分分析によってデータの圧縮(次元削減)を行うことで、平面上に描画したり、回帰分析の精度を上げたりすることができる。
・主成分分析は、PCAクラスを呼び出すことで簡単に行える。
・動径基底関数(カーネル)によってデータを変換することで、線形分離不可能なデータに対して主成分分析を行うことができる。これによって、線形分離不可能なデータが線形分離可能となり、機械学習が可能になる。これをカーネル主成分分析という。
・カーネル主成分分析はKernelPCAクラスを呼び出すことで簡単に行える。
今回は以上です。最後まで読んでいただき、ありがとうございました。