PyCaretでAnomaly Detection - 異常検知やってみる
PyCaretで異常検知に関連する複数のモデルを試すことができます。
やり方の日本語記事があまりなかったので、インターン先で触る機会があったので、PyCaretでの異常検知の実装方法を紹介します。
解決したい課題、狙うもの
- 異常検知とは何かの説明
- PyCaretでの異常検知の実装方法
- PyCaretに実装されている異常検知アルゴリズムの簡単な紹介
異常検知とは
異常検知とは、正解ラベルが圧倒的に少ない場合で、不正解のラベルがかなり特徴的な集合を形成しているときに使える手法です。
具体的には向上の工作機械の故障の前兆などの検知に用いられたりするようです。工場の工作機械は稼働時間に比べ故障する割合は極めて少ないです。そのため、そのような工場の工作機械のデータは正常なデータがほとんどで異常な正解ラベルを取得すること自体が難しく、そのような場合に用いられる手法が異常検知です。
他には、銀行の不正取引の監視や、医療事故、テキストの誤りなどの検知にも使われます。
深層学習では、AnoGanなどが異常検知では有名です。
PyCaretにおける異常検知
PyCaretの異常検知は教師なし学習がメインのようです。
ただ、公式のチュートリアルにはPyCaretの異常検知モジュールは分類のAUCや回帰のR2(決定係数)のような教理あり学習の目的を最適化するために、異常検知モデルのハイパーパラメーターを調整できる独自関数であるtune_model()
も実装しているとのことです。
PyCaret's anomaly detection module also implements a unique function tune_model() that allows you to tune the hyperparameters of anomaly detection model to optimize the supervised learning objective such as AUC for classification or R2 for regression.
今回使用するデータセット
PyCaretに同封されているUCI の Mice Protein Expression というデータセットを使用します。
これは、大脳皮質のタンパク質に関するデータセットらしいです。77個のタンパク質から形成されていて、それぞれのタンパク質に関して1,080の測定値が含まれるようです。
データセットの取得
データセットはPyCaretに入っているので、以下のように簡単に取得することができます。
from pycaret.datasets import get_data
dataset = get_data('mice')
dataset.shape
# (1080, 82)
データの分割
ここがある意味混同しやすいのですが、データの分割はtrain/evalの分割ではなくてtestの分割で、学習時には一切使用のできないデータになります。ここでは、チュートリアルに従って5%だけ切り取ることにします。
data = dataset.sample(frac=0.95, random_state=786)
data_unseen = dataset.drop(data.index)
data.reset_index(drop=True, inplace=True)
data_unseen.reset_index(drop=True, inplace=True)
print('Data for Modeling: ' + str(data.shape))
print('Unseen Data For Predictions: ' + str(data_unseen.shape))
# Data for Modeling: (1026, 82)
# Unseen Data For Predictions: (54, 82)
PyCaret環境で前処理
以下のコマンドで前処理をします。データ型をあらかた決めてくれます。今回はそのまま進んで大丈夫ですが、実務で触っているときにカテゴリ変数と数値型を間違ってることがあったので、一応ちゃんと見た方がいいと思います。
from pycaret.anomaly import *
exp_ano101 = setup(data, normalize = True,
ignore_features = ['MouseID'],
session_id = 123)
Enterを押して先に進みます。
出力
index | Description | Value |
---|---|---|
0 | session_id | 123 |
1 | Original Data | 1026,82 |
2 | Missing Values | true |
3 | Numeric Features | 77 |
4 | Categorical Features | 4 |
5 | Ordinal Features | false |
6 | High Cardinality Features | false |
7 | High Cardinality Method | |
8 | Transformed Data | 1026,91 |
9 | CPU Jobs | -1 |
10 | Use GPU | false |
11 | Log Experiment | false |
12 | Experiment Name | anomaly-default-name |
13 | USI | 4a55 |
14 | Imputation Type | simple |
15 | Iterative Imputation Iteration | None |
16 | Numeric Imputer | mean |
17 | Iterative Imputation Numeric Model | None |
18 | Categorical Imputer | mode |
19 | Iterative Imputation Categorical Model | None |
20 | Unknown Categoricals Handling | least_frequent |
21 | Normalize | true |
22 | Normalize Method | zscore |
23 | Transformation | false |
24 | Transformation Method | None |
25 | PCA | false |
26 | PCA Method | None |
27 | PCA Components | None |
28 | Ignore Low Variance | false |
29 | Combine Rare Levels | false |
30 | Rare Level Threshold | None |
31 | Numeric Binning | false |
32 | Remove Outliers | false |
33 | Outliers Threshold | |
34 | Remove Multicollinearity | false |
35 | Multicollinearity Threshold | |
36 | Remove Perfect Collinearity | false |
37 | Clustering | false |
38 | Clustering Iteration | |
39 | Polynomial Features | false |
40 | Polynomial Degree | |
41 | Trignometry Features | false |
42 | Polynomial Threshold | |
43 | Group Features | false |
44 | Feature Selection | false |
45 | Feature Selection Method | classic |
46 | Features Selection Threshold | |
47 | Feature Interaction | false |
48 | Feature Ratio | false |
49 | Interaction Threshold |
モデルの作成
モデルを作成してみます。ここが、回帰や分類と少し違うので、戸惑うかもしれませんが、そこはPyCaret様で非常に簡単です。
僕は最初compare_models
がAnomaly Detectionにはなかったです。
以下ではfractionでパラメータ設定していますが、設定しなくても大丈夫です。
iforest = create_model('iforest')
# パラメータはこうやって設定できる
svm = create_model('svm', fraction = 0.025)
使えるモデル
使えるモデル一覧は、以下のところか
models()
でみることができます。
ID | Name | Reference |
---|---|---|
abod | Angle-base Outlier Detection | pyod.models.abod.ABOD |
cluster | Clustering-Based Local Outlier | pyod.models.cblof.CBLOF |
cof | Connectivity-Based Local Outlier | pyod.models.cof.COF |
iforest | Isolation Forest | pyod.models.iforest.IForest |
histogram | Histogram-based Outlier Detection | pyod.models.hbos.HBOS |
knn | K-Nearest Neighbors Detector | pyod.models.knn.KNN |
lof | Local Outlier Factor | pyod.models.lof.LOF |
svm | One-class SVM detector | pyod.models.ocsvm.OCSVM |
pca | Principal Component Analysis | pyod.models.pca.PCA |
mcd | Minimum Covariance Determinant | pyod.models.mcd.MCD |
sod | Subspace Outlier Detection | pyod.models.sod.SOD |
sos | Stochastic Outlier Selection | pyod.models.sos.SOS |
作成したモデルを使ってデータ分析する
作成したモデルを使ってデータ分析をするためには、assign_model()
を使います。
iforest_results = assign_model(iforest)
iforest_results.head()
一番右端から一個手前に割り振られているAnomalyがラベルで1が異常値、0が正常値です。
一番右端のAnomaly_scoreは予測されたスコアで、外れ値にはより大きな値が付与されます。
モデルのプロット
以下でt-SNEで次元圧縮してプロットします。
デフォルトがt-SNEのようで、UMAPも使えるみたいです。
plot_model(iforest)
未知のデータで予測
predict_model() 関数は、新しい未見データセットに異常ラベルを割り当てるために使用されます。iforest モデルを使って data_unseen に格納されているデータを予測します。PyCaretに公開されていなかった54個の新しいサンプルが含まれています。
unseen_predictions = predict_model(iforest, data=data_unseen)
unseen_predictions.head()
modelのセーブとロード
モデルのセーブは以下でできます。
save_model(iforest,'Final IForest Model 25Nov2020')
モデルのロードは以下でできます。
saved_iforest = load_model('Final IForest Model 25Nov2020')
new_prediction = predict_model(saved_iforest, data=data_unseen)
new_prediction.head()
Discussion