主成分分析とは何なのか、とにかく全力でわかりやすく解説する

今回は次元削減の話です。
お世話になっております。長文しか書けないBBです。

次元削減と聞くと重力系の技のような印象ですが、機械学習では特徴量の項目数を少なくする処理を指します。特徴量とは機械学習を行う際に使う数値データのことです。特徴量が例えば「幅」という項目だけならば1次元のデータ、「幅」と「奥行」なら2次元のデータとなります。

なら3次元は「幅」「奥行」「高さ」、4次元目は「時間」??5次元目なんか想像もつかない……となる方もいらっしゃるかもしれませんので補足を。次元を持たせる項目はぶっちゃけ何でもいいです。単純な話、「親指の長さ」「人差し指の長さ」と考えれば片手で5次元、両手で10次元の項目を定義したことになります。特徴量の次元なんてそんなもんだととらえてください。

次元削減でデータをシンプルに

機械学習でも特徴量が多すぎると精度が悪くなってしまうことがあります。いわゆる「次元の呪い」と呼ばれる現象ですが、小難しいことを抜きにしても高次元のデータというのは扱いにくいものです。せめて3次元までのデータであれば図に落とし込むことができますので視覚的にも傾向を把握しやすくなります。データの次元数を削減する手法として、とりあえず取っ付き辛いと評判(僕個人の感想)の主成分分析が今回のお題です。

簡単に言ってしまえば主成分分析とはなんなのか

主成分分析ってもうすでに小難しそうな響きですが、なにをするのかイメージすることは難しくないのでまずは図で理解してきましょう。

散布図の中に青い直線が引かれており、それぞれのデータから青直線に向かって直角になるように赤い矢印が下ろしてあります。主成分分析ではこの青直線とそれぞれの赤矢印がぶつかったところにデータを写し取っていきます。この処理によってそれぞれの点が青直線のどこにあるか1つの数値で決まることになります。つまり、XとYの2次元だったデータが、1次元のデータに次元が削減されたことになりますね。ではこの青直線、いったいどうやって決めるのかというと、図に示したようにそれぞれのデータが1番ばらつくように引いた線になります。なぜこんな定義になっているのかといえば、「直線に写し取った結果失う情報量が最も少なくなるようにする為」というのが答えになります。この場合、失われる情報というのは直線とそれぞれの点の距離(赤矢印)になります。これが主成分分析の第1主成分の定義です。

第1とついている以上、第2もあるのはうすうす感づいているのではないでしょうか。では第2主成分は何なのか。2番目にばらつきが大きくなる線か?とお考えの人も多いでしょうが残念。僕もネットの拾い読みで信じていた口ですが、これはちょっと考えればおかしいことに気づきます。なぜなら2番目にばらつきが大きい直線なんて、第1主成分で使った青直線をほんのちょっとずらせばいいだけということになってしまいます。では何をもって第2主成分というのか、それは第1主成分が捨ててしまった情報、つまり赤矢印方向の直線に写し取った情報なのです。図にしたらこんな感じです。

この図で使ったデータは2次元のデータなので第1主成分と第2主成分でその位置を情報を失うことなく(失わないように第2主成分を定義したので)完全に表すことができます。要するに主成分分析とは図の横軸と縦軸を青とオレンジで示した軸にあわせて回転させただけだったわけです。

これで分かったことがあります。今回、扱ったのは2次元のデータですので縦横の2軸を回転させることでできる第1、第2主成分が存在していましたが、もし取り扱ったのが3次元データであればどうだったでしょうか。縦横奥行の3軸を回転させることで主成分分析が行われていたと思いませんか?そう、3次元データでは第3主成分まで定義することができるわけなのです。もっと一般的にいえばM次元のデータは第M主成分まで定義できてしまうということがわかりますね。

NumPyで実装する主成分分析

さて、主成分分析についてのイメージがついたところでNumPyであっさり実装してみましょう。

実行結果

計算に使ったデータはおなじみscikit-learnのirisデータセットです。実行結果の図は1枚目が変換前のデータに変換用の軸を上書きしたものです。2枚目の上の図は第1主成分を横軸に、第2主成分を縦軸に取った図です。2枚目の中下段は変換用の軸にデータを射影した結果です。プロットはラベル毎に色分けされており、3種類のクラスに分けられます。うまいこと、変換軸をもとに変換できていることが分かります。また、射影した図を見てみると第1主成分のデータでは3種類のクラスが分けられていますが、第2主成分のデータはごちゃごちゃに混ざってしまっています。

上記はirisデータセットを切り出して2次元データとして扱っていますが、全部使うと4次元のデータになります。4次元データ全てを使った結果がこちらです。

4次元データを使っていますので、第1~第4主成分まで計算することができます。それぞれの軸に射影した図を見てみるとやはり第1主成分ではクラス分けができそうですが、第2~第4主成分はごちゃついてしまってクラス分類どころではなさそうですね。

さて、実際に数値を使って図を作ってみましたが主成分分析のイメージは固まってきたでしょうか。あっさりしたソースコードになっていますがいったい何をやっているのか、次の章で数式を見ながらコードの内容を理解していきましょう。

数式で理解する主成分分析

主成分分析に取り掛かるまでにいくつか知っておきたいことがありますので、ちょちょっとまとめていきます。

分散と共分散

先の説明で少し触れましたが、第1主成分を射影する軸の方向はデータが最もばらつく方向にとると説明しました。このデータのばらつきの指標に分散:V_{x}があります。式で書くとこうなります。

    \begin{eqnarray*} V_{x}= \frac{1}{n}\sum_{i=1}^{n}\left ( x_{i}-\bar{x}  \right )^{2} \nonumber\end{eqnarray}

日本語に訳すと、1~n個までのデータ:x_{i}からそれぞれ平均:\bar{x}を引いたもの(これを偏差といいます)の2乗を全部足し合わせてnで割った数が分散となります。式を見る通り、平均から離れているデータが多いほど分散が大きくなります。逆に一定の値をとるようなデータであれば分散は0に近づいていきます。また、( x_{i}-\bar{x}  )^{2}  は2乗をとっていますので、xが実数である限りは分散は0以上となります。

分散はxという1つのデータのみ扱いましたが、今度は別のデータyが登場します。この2つから共分散:S_{xy}を計算します。

    \begin{eqnarray*} S_{xy}\left ( x, y \right ) = \frac{1}{n}\sum_{i=1}^{n}\left ( x_{i}-\bar{x}  \right )\left ( y_{i}-\bar{y}  \right ) \nonumber\end{eqnarray}

分散の式に似ていますが、共分散はxyの偏差のかけ合わせた数を足し合わせています。同じ数の2乗の足し合わせだった分散とは違って共分散は正の値も負の値もどちらもとることができます。共分散は2つのデータがどのような傾向にあるかを簡単に示す指標になっています。例えばxが正の値をとるとき、yが負の値をとるとすると共分散は負の値となります。両方とも正の値をとる場合、分散は正の値となるわけです。グラフにすると傾きが正の分布は共分散は正、傾きが負の分布は共分散が負になりやすいといえます。

分散共分散行列

高次元のデータを考えたときに分散、共分散の組み合わせがたくさんになってしまい書くのが面倒になりますので行列にまとめてしまおうというのが分散共分散行列です。わかりやすくする為、ここではxyの2次元データを考えていきましょう。まずはこんな行列を定義します。

    \begin{eqnarray*} X = \begin{bmatrix} x_{1}-\bar{x} &y_{1}-\bar{y}\\ \vdots&\vdots \\ x_{n}-\bar{x} &y_{n}-\bar{y} \end{bmatrix} \nonumber\end{eqnarray}

xyの偏差を1~nまでがんがん並べていっています。その行列にこんなことをします。行列式の計算はちょっと癖がありますので、よくわからないという方は前回記事を参考にしてみてください。

    \begin{eqnarray*} \begin{split} \frac{1}{n}X^{T}X &= \frac{1}{n}\begin{bmatrix} x_{1}-\bar{x} &\hdots  &x_{n}-\bar{x} \\ y_{1}-\bar{y} &\hdots  &y_{1}-\bar{y} \end{bmatrix} \begin{bmatrix} x_{1}-\bar{x} &y_{1}-\bar{y}\\ \vdots&\vdots \\ x_{n}-\bar{x} &y_{n}-\bar{y} \end{bmatrix}\\ &=\frac{1}{n}\begin{bmatrix} \left ( x_{1}-\bar{x} \right )^{2}+\hdots+\left ( x_{n}-\bar{x} \right )^{2} &\left ( x_{1}-\bar{x} \right )\left ( y_{1}-\bar{y} \right )+\hdots+\left ( x_{n}-\bar{x} \right )\left ( y_{n}-\bar{y} \right ) \\ \left ( x_{1}-\bar{x} \right )\left ( y_{1}-\bar{y} \right )+\hdots+\left ( x_{n}-\bar{x} \right )\left ( y_{n}-\bar{y} \right ) & \left ( y_{1}-\bar{y} \right )^{2}+\hdots+\left ( y_{n}-\bar{y} \right )^{2} \end{bmatrix}\\ &=\begin{bmatrix} V_{x} & S_{xy}\\ S_{xy} & V_{y} \end{bmatrix} \end{split} \nonumber\end{eqnarray}

途中式は面倒でしたが見ごとにxyの分散、共分散からなる行列を計算することができました。

主成分分析

前置きが長くなりましたがいよいよ主成分分析について考えていきたいと思います。今回もxyの2次元データを使って考えていきましょう。主成分分析は2次元データの場合、縦軸と横軸を回転させた新しい座標系にデータを変換させる処理だということは既に説明しました。では変換後のデータをzと置くとxyの関係はこのように表すことができます。zは第1主成分なのか、第2主成分なのか気になる方もいるかもしれませんが、いったん心の中にしまってください。

(1)   \begin{eqnarray*} z_{i} = a_{1}x_{i}+a_{2}y_{i} \end{eqnarray*}

ここでおもむろにzの分散:V_{z}を求めてみます。お忘れかもしれませんが、この分散が最大になるようz、もとい変換に使われるパラメタのa_{1}a_{2}を求めることが主成分分析のポイントです。V_{z}は以下の式で表せます。

(2)   \begin{eqnarray*} \begin{split} V_{z}&=\frac{1}{n}\sum_{i=1}^{n}\left (z_{i}-\bar{z} \right )^2\\ &=\frac{1}{n}\sum_{i=1}^{n}\left \{ \left ( a_{1}x_{i}+a_{2}y_{i} \right )-\left ( a_{1}\bar{x}+a_{2}\bar{y} \right ) \right \}^2\\ &=\frac{1}{n}\sum_{i=1}^{n}\left \{ a_{1}\left ( x_{i}-\bar{x} \right )+a_{2}\left ( y_{i}-\bar{y} \right ) \right \}^2\\ &=\frac{1}{n}\sum_{i=1}^{n}\left \{ a_{1}^2\left ( x_{i}-\bar{x} \right )^2+2a_{1}a_{2}\left ( x_{i}-\bar{x} \right )\left ( y_{i}-\bar{y} \right )+a_{2}^2\left ( y_{i}-\bar{y} \right )^2 \right \}\\ &=a_{1}^2V_{x}+2a_{1}a_{2}S_{xy}+a_{2}^2V_{y} \end{split} \end{eqnarray*}

V_{z}xyの分散と共分散で表すことができました。
今度はa_{1}a_{2}についてもう少し考えてみます。a_{1}a_{2}をそれぞれa_{1}=\cos\theta_{1}a_{2}=\cos\theta_{2}と置きます。\theta_{1}\theta_{2}はそれぞれzに変換するための軸とx軸、y軸との角度になっています。詳しいことは省きますが、このようなa_{1}a_{2}を方向余弦といいます。このように定義することでa_{1}a_{2}には以下の関係というか制限ができます。

(3)   \begin{eqnarray*} a_{1}^2+a_{2}^2=1 \end{eqnarray*}

式(2)と式(3)を使って、V_{z}が最大になるa_{1}a_{2}を求めていきます。式(2)のような方程式と式(3)のような条件式がそろうとLagrangeの未定乗数法を使って答えを出すことができます。色々出てきて頭がパンクしてしまいましたが、もう少しです。
Lagrangeの未定乗数法とは「求めたい変数の定義式:式(2) – \lambdax条件式:式(3)」を関数Fとして変数a_{1}a_{2}\lambdaの偏微分が0になるようにa_{1}a_{2}\lambdaを求めるとV_{z}が最大になるという魔法のような解法です。……お気持ちはわかります。この段階でしれっと変数が追加された憤りはひしひしと。では関数Fと偏微分を解いていきましょう。
関数F

(4)   \begin{eqnarray*} F\left ( a_{1},a_{2},\lambda \right ) = a_{1}^2V_{x}+2a_{1}a_{2}S_{xy}+a_{2}^2V_{y} - \lambda(a_{1}^2+a_{2}^2-1) \end{eqnarray*}

偏微分式

(5)   \begin{eqnarray*} \frac{\partial F\left ( a_{1},a_{2},\lambda \right )}{\partial a_{1}}=2a_{1}V_{x}+2a_{2}S_{xy}-2\lambda a_{1} =0 \end{eqnarray*}

(6)   \begin{eqnarray*} \frac{\partial F\left ( a_{1},a_{2},\lambda \right )}{\partial a_{2}}=2a_{1}S_{xy}+2a_{2}V_{y}-2\lambda a_{2} =0 \end{eqnarray*}

(7)   \begin{eqnarray*} \frac{\partial F\left ( a_{1},a_{2},\lambda \right )}{\partial \lambda }=-a_{1}^2-a_{2}^2+1=0 \end{eqnarray*}

式(7)は式(3)と同様なので用済みです。式(5)と式(6)は下のような行列式に書き換えることで知っている人なら知っている固有値問題になります。さっさとやってしまいましょう。

(8)   \begin{eqnarray*} \begin{bmatrix} a_{1}V_{x}+a_{2}S_{xy}\\ a_{1}S_{xy}+a_{2}V_{y} \end{bmatrix} = \begin{bmatrix} V_{x} &S_{xy} \\ S_{xy} & V_{y} \end{bmatrix} \begin{bmatrix} a_{1}\\ a_{2} \end{bmatrix}= \lambda \begin{bmatrix} a_{1}\\ a_{2} \end{bmatrix} \end{eqnarray*}

ここから分散共分散行列の固有方程式を解くことでa_{1}a_{2}\lambdaが求まります。詳細な解法についてはこちらを参照いただくとしてこの場合は以下の式を解いていきます。

(9)   \begin{eqnarray*} \begin{split} \left | \begin{bmatrix} V_{x} &S_{xy} \\ S_{xy} &V_{y} \end{bmatrix} -\begin{bmatrix} \lambda  &0 \\ 0 &\lambda \end{bmatrix}\right |&= \left | \begin{bmatrix} V_{x}-\lambda &S_{xy} \\ S_{xy} &V_{y}-\lambda \end{bmatrix} \right |\\ &=\left ( V_{x}-\lambda \right )\left ( V_{y}-\lambda \right )-S_{xy}^2 &=0 \end{split} \end{eqnarray*}

上記の通り\lambdaの2次方程式となりましたので、2つの\lambdaが求まったことになります。それぞれの\lambdaからa_{1}a_{2}を求めることができます。2つの\lambdaのうち大きいほうが第1主成分、小さいほうが第2主成分となっており、それぞれに対応するa_{1}a_{2}が変換軸を表すベクトルになっています。

まとめ

長い……今回も長かった……。最初の方の内容は執筆していく過程で忘れてしまったので、主成分分析とはなんぞやというところを改めてまとめますね。

  1. 主成分分析は特徴量の次元削減に使われる手法だよ。
  2. 次元数Mの特徴量の場合、主成分分析は第1~第M主成分まで求められるよ。
  3. 分散共分散行列をいろいろやると最終的に固有値問題にいきつくよ。

多少、説明が荒くなった部分(最後のほう)もありますが、なんとなく主成分分析について警戒心がほぐれたと感じていただければ幸いです!

最近の記事

  • 関連記事
  • おすすめ記事
  • 特集記事

アーカイブ

カテゴリー

PAGE TOP