データ分析
Julia
主成分分析

PCAで似ている飛行機を探す


Abstract

この記事は,東京大学航空宇宙工学科/専攻 Advent Calendar 2018向けの記事です.

こちらにある航空機の機体諸元データセットに対してPCAによる次元削減をかけて,各機体の特徴量ベクトルのコサイン類似度を計算し似ている航空機のペアを見つけようと思います.


Introduction

航空機の機体諸元データセットには各機体の主翼面積や全長,着陸重量などの色々なデータがすくまれています.しかし全てのデータが機体の特徴になるかというとそうでもないし変数間の相関もあるように思います.例えばB747やA380以外の機体はエンジンは2発で共通だとか,安定性に関わる尾翼容積比はどの機体もだいたい同じだとか,全長が大きいほど主翼面積も大きくて航続距離も長くなるのでこれらの変数は相関しているだとかです.そういうのを抜きにしてもこのデータセットにおける航空機を特徴付ける変数は100種類弱ありこの中から似ている航空機を見つけるのは大変そうです.

そこで今回はPCAという次元削減の手法を使って変数の数を減らし,各機体の特徴をよく表している新しい変数を作ることにします.この新しい変数を特徴量ベクトルとみなして二つの特徴量ベクトルのコサイン類似度を計算し似ている機体の組み合わせを探していきます.結果を先に言うと似ている航空機のペアだと同シリーズの機体(派生型ってやつです.B747シリーズにおける747-300と747-400は同じ747シリーズの機体なのでほぼ同じ変数が多くなったりします)が上位に来て面白くなかったので全然似てない機体のペアも見つけることにしました.

PCAと結果の可視化にはJulia 1.0を用いました.jupyter notebookに書いていたのですがコードが汚いので整理してコードをあげようと思います(コードをあげるとは言ってない).


PCA(主成分分析)


PCAとは

PCAは次元削減の手法の一つです.多数の変数から,少数の分散の大きい成分を合成してデータを要約してくれます.


導出

二次元のデータを一次元空間に写像する場合を考えます.目標は分散が最大になるような方向へ写像することで,この方向$\boldsymbol{u_1}$を求めることです.簡単のため$\boldsymbol{u_1}$を単位ベクトルつまり$\boldsymbol{u_1}^T \boldsymbol{u_1}=1$としておきます.

各データ点$\boldsymbol{x_i}$は$\boldsymbol{u_1}^T \boldsymbol{x_i}$上に射影され,サンプル集合の平均を$\boldsymbol{\mu}=\frac{1}{n}\sum_{i=1}^n \boldsymbol{x_i}$とすると射影されたデータの平均は$\boldsymbol{u_1}^T \boldsymbol{\mu}$になります.射影されたデータの分散は以下のようになります.

\begin{align}

\displaystyle\frac{1}{n}\sum_{i=1}^n \{ \boldsymbol{u_1}^T \boldsymbol{x_i} - \boldsymbol{u_1}^T \boldsymbol{\mu}\}^2&=\frac{1}{n}\sum_{i=1}^n \{\boldsymbol{u_1}^T (\boldsymbol{x_i} - \boldsymbol{\mu})\}^2\\
&=\frac{1}{n}\sum_{i=1}^n \boldsymbol{u_1}^T (\boldsymbol{x_i} - \boldsymbol{\mu})(\boldsymbol{x_i}-\boldsymbol{\mu})^T\boldsymbol{u_1}\\
&=\boldsymbol{u_1}^T \boldsymbol{S}\boldsymbol{u_1}
\end{align}

ここで$S$は共分散行列です.

次にやることは射影されたデータの分散${\boldsymbol{u_1}}^T\boldsymbol{S}\boldsymbol{u_1}$を正規化条件${\boldsymbol{u_1}}^T\boldsymbol{u_1}=1$のもとで最大化することです.これはラグランジュ乗数$\lambda$を用いて

{\boldsymbol{u_1}}^T\boldsymbol{S}\boldsymbol{u_1}-\lambda (1-{\boldsymbol{u_1}}^T\boldsymbol{u_1})

を最大化することに等しいわけですがこれの$\boldsymbol{u_1}$についての微分を考えれば結局$\boldsymbol{Su_1}=\lambda \boldsymbol{u_1}$という固有値問題を解くのと同じになります.結局射影されたデータの分散は最大固有値に対する固有ベクトルを選んだ時に最大になり,この固有ベクトルを第一主成分といいます.その他の主成分も既に得られている主成分ベクトルに直交するという条件で分散を最大にする方向を選ぶことで得ることができます.


variance explained

今までで第$i$主成分を得ることができるようになったわけですがでは何個の主成分を得ればいいのでしょうか.ここでvariance explainedを考えることになります.分散共分散行列の導出でデータ$x$を射影した時の分散を最大化することを考えましたが,この分散は${\boldsymbol{u_1}}^T S\boldsymbol{u_1}={\boldsymbol{u_1}}^T\lambda\boldsymbol{u_1}=\lambda$になったのでした.つまり$S$の固有値を大きい順に並べたものを$\boldsymbol{\lambda}=[\lambda_1 ,\lambda_2 ,\cdots \lambda_n]$とすると,($i$番目の固有値までの和)/(全固有値の和)を計算すれば$i$番目の固有値まででどれだけ全データの分散を表現できるかを計算できるわけです.一般にこの値が0.99を超えるように次元削減したあとの次元を決めるようなのでこのvariance explainedも計算できるようにしておきます.


補足

PCAのざっくりした説明は以上になるのですが世の中のPCAライブラリはこのように実装されているかと言うとそういうわけではありません.分散共分散行列をいちいち計算するのがだるいので.PCAとSVDの関連についてという記事に書かれていますが実はSVDはPCAと同じようなことをしていますのでライブラリの実装もSVDを利用したものが多いようです(例えばscikit-learnのPCAのソースコードをみるとここでSVDしているのがわかります.この下のsvd_flipによって固有値の符号を揃える操作をしているのでscikit-learnとスクラッチで実装した場合の結果が合わないのですがあまり気にせずに行きます).

SVDの説明を読むと,SVDもより低次元でデータの特徴をよく表す部分空間を求めることっぽいですね.このとき元の空間でのデータと部分空間の距離が最小にしたいわけですが,元の空間のデータは固定なのでこのことは部分空間に写像されたデータの分散を最大化するのと同じです.前者がSVDの説明で後者がPCAの導出ででてきたやつですね.


結果

10番目の固有値までとるとvariance explained=0.9998になったので十分だろうということで10次元まで削減していきます.また,もとの機体諸元のデータは欠損値が多いのですがすべて0で補間したものをもちいました.


散布図

第1,2主成分で張られる平面上に散布図を描いた結果は以下のようになりました.

pca.png

2番目の固有値まで取った時のvariance explained=0.9868となりこれだけでだいたいの特徴が表されているはずですが,機体の種類が多くて見にくいのを差し引いてもなんともいえない散布図ですね…


似ている航空機のペア

元データは欠損値が多いので欠損値の割合が25%以下のデータを抽出して主成分空間にとばしたあとの特徴量ベクトルについてコサイン類似度を計算して大きい順に出力しました.派生型は抜きにしていくつか列挙するとこんな感じです.コサイン類似度=>航空機のペア という形式で出力していて,最初のアルファベットはAがAirbus,DOUG.MDが今はなきマクドネル・ダグラスを表していて7から始まるのはBoeingの機体です.

0.999945 => "A300-600R+A310-300"

0.999856 => "747-200+A340-600"
0.999835 => "767-200ER+A340-200"
0.999829 => "747-400+DOUG.MD-11"
0.999826 => "A320-200+DOUG.MD-83"
0.999788 => "747-200+A340-200"
0.999787 => "757-200+767-300"
0.999677 => "767-300ER+A340-200"
0.999668 => "767-300+A330-300"
0.999612 => "747-100+A330-300"
0.999593 => "767-300ER+A330-200"
0.999538 => "A330-200+A340-200"

ぶっちゃけここに挙げたペアはコサイン類似度がどれも0.9995以上と全部似てるんじゃないかと思う一方でいや流石に別のシリーズの機体同士がこんなに似ているのはおかしいのではとも思いますね.B767とA330は比較してどうなのかと言う記事の最後に乗客数と航続距離のグラフがあるのですが,これを見るとB757-200とB767-300はほぼ同じ航続距離なので似ているのもわかるのですがB767-300ERとA330-200は全然違うように見えます.


似ていない航空機のペア

似ている航空機のペアを見てもよくわからないので今度は似ていない航空機のペアを見てみましょう.EMBはEmbraer,Reg. JetはBombardierの機体を表しています.

0.156235 => "A330-200+EMB-145.1"

0.145921 => "A340-300+EMB-145.1"
0.14175 => "747-200+Reg. Jet100ER.1"
0.132862 => "747-200+EMB-145.1"
0.127075 => "A340-600+EMB-145.1"

これは先ほどと違って解釈しやすい結果です.EMB-145.1はERJ 145,Reg. Jet100ERはCRJ 100のことなわけですが,両方とも乗客数が50人弱のリージョナルジェット機といわれるもので航続距離は1200~1500nm程度です.これに対してA340やB747は400~500人は乗れる大型旅客機で航続距離もA340は8000nm程度とだいぶ長い機体ですので類似度が小さくなるのも頷ける話ですね.


最後に

いろいろ書きましたが欠損値を全部0にしているのでぐちゃぐちゃな結果になっている気がします.欠損値が少ないデータだけでPCAをかけるとそもそも機体の種類があまりに少なくなってしまい面白くないのでこのようにしたのですが,ちゃんとやるならJane年鑑を写経するべきだったかもしれません.