PyOD: Pythonによる異常検知入門

PyODは、異常検知のための非常に包括的なPythonライブラリで、LOF(Local Outlier Factor)やIsolation Forestといった古典的な手法から、最新の深層学習モデルまで、幅広い異常検知アルゴリズムを網羅しています。大規模なデータセットに対しても効率的に処理できるスケーラビリティや、各アルゴリズムが独立したモジュールとして実装されていることが特徴です。またscikit-learnと同様のインターフェースを採用しているため、既存のデータ分析パイプラインに容易に組み込むことができるといった特徴も持ちます。今回は、PyODによる異常検知の実装方法を紹介します。
異常検知とは?
機械学習における異常検知とは、大量のデータの中から、通常のデータから大きく外れる値やパターン、つまり異常値を自動的に見つける技術です。これらの異常値は、システムの故障、不正行為、製品の不良など、様々な問題の早期発見につながる重要な手がかりとなります。
なぜ異常検知が重要なのか?
- 問題の早期発見: 異常を早期に検知することで、システムダウンや製品不良による大きな損害を防ぐことができます。
- 効率的な運用: 膨大なデータを人が目視でチェックする手間を省き、効率的な運用を実現します。
- 新しい発見: 異常値の中に、新しい製品やサービスのアイデアにつながる貴重な情報が隠れている可能性もあります。
異常検知の手法
異常検知の手法は大きく分けて以下の2つがあります。
- 教師あり学習: 過去のデータから正常と異常のラベル付けを行い、そのデータをもとにモデルを学習させます。
- 教師なし学習: 正常なデータのみを学習させ、新しいデータがどれだけ正常なデータから外れているかを評価します。
代表的な手法としては、以下のものが挙げられます。
- 統計的手法: 平均値や標準偏差など、統計的な指標を用いて異常値を検出します。
- 機械学習: サポートベクターマシン、ニューラルネットワーク、深層学習など、様々な機械学習アルゴリズムが利用されます。
- 深層学習: オートエンコーダーや生成モデルなど、深層学習を用いた手法が近年注目されています。
PyODの特徴
PyODは、多変量データにおける異常値(外れ値)検出のための、Pythonライブラリで、2017年のリリース以来、学術研究やビジネス領域で広く利用されており、2200万回以上のダウンロード数を誇ります。異常検知という、非常に挑戦的な分野において、PyODはデファクト・スタンダードなツールとなっています。
PyODの主な特徴
- 統一的で使いやすいインターフェース: 多様なアルゴリズムを共通のAPIで利用できるため、学習コストを低減し、様々な手法を簡単に試すことができます。
- 幅広いモデル: 古典的なLOF (SIGMOD 2000)から、最新の深層学習モデル(PyTorchベース)まで、50種類以上の検出アルゴリズムを搭載しています。
- 高性能かつ効率的: numbaやjoblibを用いたJITコンパイルと並列処理により、高速な処理を実現しています。
- 高速な学習と予測: SUODフレームワークにより、学習と予測の時間を短縮できます。
- 活発なコミュニティ: Analytics Vidhya、KDnuggets、Towards Data Scienceなど、数多くの機械学習コミュニティで取り上げられ、豊富な情報やチュートリアルが提供されています。
PyODが選ばれる理由
- 多様性: 様々な種類のデータや異常パターンに対応できる多様なアルゴリズムが用意されています。
- 使いやすさ: 直感的なAPIと豊富なドキュメントにより、初心者でも簡単に利用できます。
- 性能: 大規模なデータセットに対しても高速に処理できます。
- 信頼性: 数多くの研究者やエンジニアによって利用されており、その信頼性は実証されています。
PyODに実装されているアルゴリズム
ここでは、PyODに実装されている異常検知アルゴリズムをまとめます。
個々の検出アルゴリズム
Type | Abbr | Algorithm | Year |
---|---|---|---|
Probabilistic | ECOD | 経験的累積分布関数を用いた教師なし外れ値検出 | 2022 |
Probabilistic | ABOD | 角度ベースの外れ値検出 | 2008 |
Probabilistic | FastABOD | 近似法を用いた高速角度ベース外れ値検出 | 2008 |
Probabilistic | COPOD | コピュラベースの外れ値検出 | 2020 |
Probabilistic | MAD | 中央絶対偏差 | 1993 |
Probabilistic | SOS | 統計的外れ値選択 | 2012 |
Probabilistic | QMCD | 準モンテカルロ 不一致外れ値検出 | 2001 |
Probabilistic | KDE | カーネル密度関数による外れ値検出 | 2007 |
Probabilistic | Sampling | サンプリングによる高速距離ベース外れ値検出 | 2013 |
Probabilistic | GMM | 外れ値分析のための確率的混合モデリング | |
Linear Model | PCA | 主成分分析(固有ベクトル超平面への加重投影距離の合計) | 2003 |
Linear Model | KPCA | カーネル主成分分析 | 2007 |
Linear Model | MCD | 最小共分散行列式(外れ値スコアとしてマハラノビス距離を使用) | 1999 |
Linear Model | CD | クックの距離を用いた外れ値検出 | 1977 |
Linear Model | OCSVM | 1-クラス サポートベクターマシン | 2001 |
Linear Model | LMDD | 偏差ベースの外れ値検出 | 1996 |
Proximity-Based | LOF | 局所外れ値係数 | 2000 |
Proximity-Based | COF | 接続性に基づく外れ値係数 | 2002 |
Proximity-Based | (Incremental) COF | メモリ効率の高い接続ベースの外れ値係数(速度は遅いが、ストレージの複雑さを軽減) | 2002 |
Proximity-Based | CBLOF | クラスタリングベースの局所外れ値係数 | 2003 |
Proximity-Based | LOCI | 局所相関積分を用いた高速外れ値検出 | 2003 |
Proximity-Based | HBOS | ヒストグラムベースの外れ値スコア | 2012 |
Proximity-Based | kNN | k-最近謗法(k 番目に近い近傍点までの距離を外れ値スコアとして使用) | 2000 |
Proximity-Based | AvgKNN | 平均値 k-最近謗法 (k近傍点までの平均距離を外れ値スコアとして使用) | 2002 |
Proximity-Based | MedKNN | 中央値 k-最近謗法 (k近傍点までの距離の中央値を外れ値スコアとして使用) | 2002 |
Proximity-Based | SOD | 部分空間外れ値検出 | 2009 |
Proximity-Based | ROD | 回転ベースの外れ値検出 | 2020 |
Outlier Ensembles | IForest | アイソレーション・フォレスト | 2008 |
Outlier Ensembles | INNE | 最近傍アンサンブルを用いたアイソレーション・ベースの異常検出 | 2018 |
Outlier Ensembles | DIF | 異常検出のための深層アイソレーション・フォレスト | 2023 |
Outlier Ensembles | FB | 特徴量バギング | 2005 |
Outlier Ensembles | LSCP | 並列外れ値アンサンブルの局所選択的組み合わせ | 2019 |
Outlier Ensembles | XGBOD | エクストリームブースティングベースの外れ値検出(教師あり) | 2018 |
Outlier Ensembles | LODA | 軽量オンライン異常検出 | 2016 |
Outlier Ensembles | SUOD | 大規模教師なし異種外れ値検出高速化 | 2021 |
Neural Networks | AutoEncoder | Fully connected オートエンコーダ(再構築エラーを外れ値スコアとして使用) | |
Neural Networks | VAE | 変分オートエンコーダ(再構築エラーを外れ値スコアとして使用) | 2013 |
Neural Networks | Beta-VAE | 変分オートエンコーダー (カスタマイズされた損失項) | 2018 |
Neural Networks | SO_GAAL | 単目的敵対的生成アクティブ・ラーニング | 2019 |
Neural Networks | MO_GAAL | 多目的敵対的生成アクティブ・ラーニング | 2019 |
Neural Networks | DeepSVDD | 深層 1-クラス分類 | 2018 |
Neural Networks | AnoGAN | 敵対的生成ネットワークによる異常検出 | 2017 |
Neural Networks | ALAD | 敵対的学習による異常検出 | 2018 |
Neural Networks | AE1SVM | オートエンコーダベースの 1-クラス サポート ベクター マシン | 2019 |
Neural Networks | DevNet | 偏差ネットワークによる深層異常検出 | 2019 |
Graph-based | R-Graph | Rグラフによる外れ値検出 | 2017 |
Graph-based | LUNAR | グラフニューラルネットワークによる局所外れ値検出手法の統合 | 2022 |
外れ値アンサンブルと外れ値検出器の組み合わせ
Type | Abbr | Algorithm | Year |
---|---|---|---|
Outlier Ensembles | FB | 特徴量バギング | 2005 |
Outlier Ensembles | LSCP | 並列外れ値アンサンブルの局所選択的組み合わせ | 2019 |
Outlier Ensembles | XGBOD | エクストリームブースティングベースの外れ値検出(教師あり) | 2018 |
Outlier Ensembles | LODA | 軽量オンライン異常検出 | 2016 |
Outlier Ensembles | SUOD | 大規模教師なし異種外れ値検出高速化 | 2021 |
Outlier Ensembles | INNE | 最近傍アンサンブルを用いたアイソレーション・ベースの異常検出 | 2018 |
Combination | Average | スコアの平均による単純組み合わせ | 2015 |
Combination | Weighted Average | 検出器の重みでスコアを平均化する単純組み合わせ | 2015 |
Combination | Maximization | 最大スコアを取る単純組み合わせ | 2015 |
Combination | AOM | 最大値の平均 | 2015 |
Combination | MOA | 平均の最大化 | 2015 |
Combination | Median | スコアの中央値を取る単純組み合わせ | 2015 |
Combination | Majority Vote | ラベルの多数決による単純組み合わせ(重み付けも可能) | 2015 |
PyODのインストール方法と使い方
PyOD は、pip または conda を使用して簡単にインストールできます。頻繁に更新および機能強化が行われるため、最新バージョンを使用することが推奨されています。
$ pip install pyod # normal install
$ pip install --upgrade pyod # or update if needed
$ conda install -c conda-forge pyod # using conda
また、PyOD に実装されている特定のアルゴリズムを利用するためには、追加で以下のパッケージをインストールする必要があります。
- combo (
models/combination.py
およびFeatureBagging
に必要) - pytorch (
AutoEncoder
およびその他のディープラーニング モデルに必要) - suod (
SUOD
モデルの実行に必要) - xgboost (
XGBOD
に必要) - pythresh (
thresholding
に必要)
次に、PyODの使い方ですが、scikit-learnと同じように実装できます。サンプルコードを以下に紹介します。
# -*- coding: utf-8 -*- from pyod.models.knn import KNN # kNN detector from pyod.utils import generate_data from pyod.utils.data import evaluate_print from pyod.utils.example import visualize contamination = 0.1 # 外れ値の混入率 n_train = 200 # 学習データ数 n_test = 100 # テストデータ数 # データ生成 X_train, X_test, y_train, y_test = generate_data( n_train=n_train, n_test=n_test, contamination=contamination ) # KNN 検出器の訓練 clf_name = 'KNN' clf = KNN() clf.fit(X_train) # 学習データに対する予測ラベルと外れ値スコアを取得 y_train_pred = clf.labels_ # 2 クラスラベル (0: 正常, 1: 外れ値) y_train_scores = clf.decision_scores_ # 生のスコア # テストデータに対する予測を行う y_test_pred = clf.predict(X_test) # 外れ値ラベル (0 or 1) y_test_scores = clf.decision_function(X_test) # 外れ値スコア # 予測信頼度も取得可能 (ラベルと信頼度 [0.0~1.0]) y_test_pred, y_test_pred_confidence = clf.predict( X_test, return_confidence=True ) # 評価と結果の出力 print("\n学習データ:") evaluate_print(clf_name, y_train, y_train_scores) print("\nテストデータ:") evaluate_print(clf_name, y_test, y_test_scores) # 結果の可視化 visualize( clf_name, X_train, y_train, X_test, y_test, y_train_pred, y_test_pred, show_figure=False, save_figure=True )
各異常検出アルゴリズムのクラスには、共通して以下のメソッドが実装されています。
fit(X)
: 検出器を学習します。パラメータy
は、教師なし手法では無視されます。decision_function(X)
: 学習した検出器を使用して、X
の生の異常スコアを予測します。predict(X)
: 学習した検出器を使用して、サンプルが外れ値であるかどうかをバイナリラベルとして判断します。predict_proba(X)
: 学習した検出器を使用して、サンプルが外れ値である確率を推定します。predict_confidence(X)
: サンプルごとにモデルの信頼性を評価します (predict
およびpredict_proba
に適用可能)decision_scores_
: トレーニング データの外れ値スコア。通常、スコアが高いほど異常な動作が多いことを示します。外れ値は通常、スコアが高くなります。labels_
: トレーニング データのバイナリ ラベル。0 は正常値、1 は外れ値/異常値を示します。
また、検出器の推論結果の精度を確認するために、evaluate_print関数を利用することができます。この関数は、以下のように、メトリックとして ROC と Precision @ n を評価します(上記コード中のL.39~42)。
学習データ:
KNN ROC:1.0, precision @ rank n:1.0
テストデータ:
KNN ROC:1.0, precision @ rank n:1.0
さらに、visualize関数を使用することで、データに対する推論結果を可視化することができます。以下、上記のコードで可視化した例になります。

まとめ
PyODは、多くのアルゴリズムを使いやすい形で実装しているため、異常検知の分野で実用的かつ効率的なツールとして確立されています。今回紹介した内容は、PyODのほんの一部分に過ぎませんので、GitHubリポジトリや公式ドキュメントを参考に、さらに便利な使い方を調べてみてください。今回の内容を活用して、皆さまのデータ分析や機械学習のプロジェクトに新たな価値をもたらす一助となれば幸いです。