正常値と異常値の区別を「マハラノビス距離」で数値化する話を「正常、異常をどう数値で判断するか?」「違いは距離で区別する」「やっと理解の糸が繋がった」で取り上げました。多変量になるとマトリクス計算になりますので、pythonを用いて計算する方法を説明いたします。いざ実行してみると、配列をどうするのか悩んでしまいました。
資料はこちら → マハラノビス距離(python)
p.1 以前示した数学と理科の試験の得点の相関プロットを左下に再掲します。赤丸が相関から外れている外れ値です。相関がある群からのマハラノビス距離DM(x、y)を式で表しています。平方根の中は、x及びyの各々の平均値を差引いた行列に共分散行列の逆行列を掛け、さらに差の行列の転置行列を掛けたものになります。 先ず①pythonで処理する準備として、数学と理科の得点を列に並べたExcelファイルを「名前を付けて保存」にして「CSV(コンマ区切り)(*.CSV)」の形式にて保存します。 今回のファイル名はMT_data.csvとしました。
p.2 pythonのスクリプトです。左上からご覧ください。jupyter notebookを起動したら、pandas、numpy、scipy及びmatplotlibをimportしておきます。データの読み込みのところでpandasを用いて読み込みます。説明用の文字、今回は1行目にM(数学)とS(理科)が入っているようなデータの場合はpandasの方が使い易いです。1行目がない場合はnumpyで読み込んでも構いません。Pandasの場合、1行目はヘッダー扱いにしてデータとして用いないことを宣言しておきます。今回は2列しかないのですが、もっとたくさんのパラメータがある場合、用いる列の名前をdata[[‘M’,’S’]]のようにして振り分けてdataに代入します。振り分けたMとSのデータを基に散布図を描いたのが左下図です。次にMとSのデータ各々の平均値及びデータから平均値を差引く計算を実行します。また共分散行列及びその逆行列を算出します。共分散は「no.cov(data)」、その逆行列は「np.linalg.pinv(cov)」で算出します。実行結果を右に示しました。
p.3 2通りの計算方法でマハラノビス距離を計算してみます。左上は、p.1の計算式をそのままスクリプトにしてあります。スクリプトの下が算出されたマハラビス距離がデータと同じ順番で表示されます。左下図は、その順番にマハラビス距離を縦軸にプロットしたものです。 Scipyの中にはマハラノビス距離を算出するスクリプトが用意されています。式を忘れても使えるので、こちらの方が便利です。scipyはpandasの配列だと使い難い場合もあります。そこで、「data.to_numpy()」というスクリプトでpandas配列をnumpy配列に変換します。マハラノビス距離はカンマで区切られたデータとして表示されます。プロットしたグラフは全く同じ図になります。
p.4 真中がデータで、左図がマハラノビス距離を縦軸に並べた図です。右は散布図です。外れ値は30番目にあり、左右の図に丸印をつけておきました。マハラノビス距離が大きいことがわかります。 2番目に高いマハラノビス距離は13番目のデータでした。右図では相関がある集団から離れています。数学と理科の相関を示す右上がりの直線に近いですが、集団の平均値から大きく外れているのでマハラビス距離が大きくなります。
今回は2変数でしたが、多変数になるとpythonによるマトリクス計算のご利益がわかってくると思われます。
今回使ったスクリプトです → MT法コード