テーブルデータの異常検知にPCAを使う【Pythonではじめる教師なし学習】

教師なし学習は、2~3次元に圧縮して可視化できるようにするとか、(どう解釈すればよいのかよくわからない)クラスターをつくる、とかくらいしか頭に入っておらず、もっときちんと使いこなせるようにしたいと思って「Pythonではじめる教師なし学習」という本で勉強をはじめました。

パラパラ見ていて、PCAで異常検知する例が面白いなと思いました。たしかに画像の異常検知でオートエンコーダー使うようなのは、教師なし学習で異常検知をしていたわけで、それも1つの教師なし学習の使いみちでした。内容を咀嚼してこちらにメモを残しておこうと思います。

 

おしながき

・PCAによる異常検知の考え方

・最適な n_components の探索

・テストデータに対するパフォーマンス評価

・異常スコアの閾値の決定

 

PCA に依る異常検知の考え方

 

PCAやオートエンコーダーのような教師なし学習を用いて異常検知をする場合の考え方は下記の通り

1. 次元削減をして、データを圧縮する(データの本質を取り出す)
2. 圧縮したデータから復元する
3. 圧縮前と復元後のデータを比較し、上手く再現できなかったものが異常であるとみなす

次元削減をした場合、データの本質的な情報は残り、本質的でない情報は失われる。復元をして、元に戻らなかったということは、そのサンプルにはデータセット全体を見た時の本質となる情報があまり含まれていなかった=異常データであるとみなす。

 

実際にやってみる

 

今回も、Kaggle のクレジットカードの不正検知のデータセットを使わせてもらいます。

ttps://www.kaggle.com/mlg-ulb/creditcardfraud

欠損値がなく、カテゴリカル変数もないきれいなデータで扱いやすいです。

前処理で標準化を施しつつ、テストデータと訓練データに分けるところまで。

 

サンプルごとに、異常の程度を定量評価したいのですが、その基準には、圧縮する前と復元した後の二乗誤差和を使います。

 

では30の特徴量がある状態から、27に削減して、また復元を行います。

復元は、pca.inverse_transform で行えます。

 

上手く検知できているかどうかは、Average Precision と PRCurve でいていきます。

7割ちょっとのRecallで7割ちょっとのPrecisionを得られるモデルができました。

今回 n_components = 27 としましたが、他の値でもっとよいパフォーマンスが出るか確認します。

27が最適だったようです。

 

テストデータに対してのパフォーマンスもみてみます。

ばっちりです。最後に異常スコアのどの値を閾値にするか決定します。

例えばrecallが0.8以上にしたい、という場合には、anomalyScore の閾値は0.0327とすれば良いことがわかります。

 

というわけで、PCAによる異常検知の整理でした。

最後まで読んでいただきありがとうございました。

 

参考

 

Pythonではじめる教師なし学習