📑

PyCaretでAnomaly Detection - 異常検知やってみる

2022/02/28に公開

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)

使えるモデル

使えるモデル一覧は、以下のところか

https://pycaret.readthedocs.io/en/latest/api/anomaly.html#pycaret.anomaly.create_model

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も使えるみたいです。

https://pycaret.readthedocs.io/en/latest/api/anomaly.html#pycaret.anomaly.plot_model

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()
GitHubで編集を提案

Discussion