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種類以上の検出アルゴリズムを搭載しています。
  • 高性能かつ効率的: numbajoblibを用いたJITコンパイルと並列処理により、高速な処理を実現しています。
  • 高速な学習と予測: SUODフレームワークにより、学習と予測の時間を短縮できます。
  • 活発なコミュニティ: Analytics VidhyaKDnuggetsTowards Data Scienceなど、数多くの機械学習コミュニティで取り上げられ、豊富な情報やチュートリアルが提供されています。

PyODが選ばれる理由

  • 多様性: 様々な種類のデータや異常パターンに対応できる多様なアルゴリズムが用意されています。
  • 使いやすさ: 直感的なAPIと豊富なドキュメントにより、初心者でも簡単に利用できます。
  • 性能: 大規模なデータセットに対しても高速に処理できます。
  • 信頼性: 数多くの研究者やエンジニアによって利用されており、その信頼性は実証されています。

PyODに実装されているアルゴリズム

ここでは、PyODに実装されている異常検知アルゴリズムをまとめます。

個々の検出アルゴリズム

TypeAbbrAlgorithmYear
ProbabilisticECOD経験的累積分布関数を用いた教師なし外れ値検出2022
ProbabilisticABOD角度ベースの外れ値検出2008
ProbabilisticFastABOD近似法を用いた高速角度ベース外れ値検出2008
ProbabilisticCOPODコピュラベースの外れ値検出2020
ProbabilisticMAD中央絶対偏差1993
ProbabilisticSOS統計的外れ値選択2012
ProbabilisticQMCD準モンテカルロ 不一致外れ値検出2001
ProbabilisticKDEカーネル密度関数による外れ値検出2007
ProbabilisticSamplingサンプリングによる高速距離ベース外れ値検出2013
ProbabilisticGMM外れ値分析のための確率的混合モデリング
Linear ModelPCA主成分分析(固有ベクトル超平面への加重投影距離の合計)2003
Linear ModelKPCAカーネル主成分分析2007
Linear ModelMCD最小共分散行列式(外れ値スコアとしてマハラノビス距離を使用)1999
Linear ModelCDクックの距離を用いた外れ値検出1977
Linear ModelOCSVM1-クラス サポートベクターマシン2001
Linear ModelLMDD偏差ベースの外れ値検出1996
Proximity-BasedLOF局所外れ値係数2000
Proximity-BasedCOF接続性に基づく外れ値係数2002
Proximity-Based(Incremental) COFメモリ効率の高い接続ベースの外れ値係数(速度は遅いが、ストレージの複雑さを軽減)2002
Proximity-BasedCBLOFクラスタリングベースの局所外れ値係数2003
Proximity-BasedLOCI局所相関積分を用いた高速外れ値検出2003
Proximity-BasedHBOSヒストグラムベースの外れ値スコア2012
Proximity-BasedkNNk-最近謗法(k 番目に近い近傍点までの距離を外れ値スコアとして使用)2000
Proximity-BasedAvgKNN平均値 k-最近謗法 (k近傍点までの平均距離を外れ値スコアとして使用)2002
Proximity-BasedMedKNN中央値 k-最近謗法 (k近傍点までの距離の中央値を外れ値スコアとして使用)2002
Proximity-BasedSOD部分空間外れ値検出2009
Proximity-BasedROD回転ベースの外れ値検出2020
Outlier EnsemblesIForestアイソレーション・フォレスト2008
Outlier EnsemblesINNE最近傍アンサンブルを用いたアイソレーション・ベースの異常検出2018
Outlier EnsemblesDIF異常検出のための深層アイソレーション・フォレスト2023
Outlier EnsemblesFB特徴量バギング2005
Outlier EnsemblesLSCP並列外れ値アンサンブルの局所選択的組み合わせ2019
Outlier EnsemblesXGBODエクストリームブースティングベースの外れ値検出(教師あり)2018
Outlier EnsemblesLODA軽量オンライン異常検出2016
Outlier EnsemblesSUOD大規模教師なし異種外れ値検出高速化2021
Neural NetworksAutoEncoderFully connected オートエンコーダ(再構築エラーを外れ値スコアとして使用)
Neural NetworksVAE変分オートエンコーダ(再構築エラーを外れ値スコアとして使用)2013
Neural NetworksBeta-VAE変分オートエンコーダー (カスタマイズされた損失項)2018
Neural NetworksSO_GAAL単目的敵対的生成アクティブ・ラーニング2019
Neural NetworksMO_GAAL多目的敵対的生成アクティブ・ラーニング2019
Neural NetworksDeepSVDD深層 1-クラス分類2018
Neural NetworksAnoGAN敵対的生成ネットワークによる異常検出2017
Neural NetworksALAD敵対的学習による異常検出2018
Neural NetworksAE1SVMオートエンコーダベースの 1-クラス サポート ベクター マシン2019
Neural NetworksDevNet偏差ネットワークによる深層異常検出2019
Graph-basedR-GraphRグラフによる外れ値検出2017
Graph-basedLUNARグラフニューラルネットワークによる局所外れ値検出手法の統合2022

外れ値アンサンブルと外れ値検出器の組み合わせ

TypeAbbrAlgorithmYear
Outlier EnsemblesFB特徴量バギング2005
Outlier EnsemblesLSCP並列外れ値アンサンブルの局所選択的組み合わせ2019
Outlier EnsemblesXGBODエクストリームブースティングベースの外れ値検出(教師あり)2018
Outlier EnsemblesLODA軽量オンライン異常検出2016
Outlier EnsemblesSUOD大規模教師なし異種外れ値検出高速化2021
Outlier EnsemblesINNE最近傍アンサンブルを用いたアイソレーション・ベースの異常検出2018
CombinationAverageスコアの平均による単純組み合わせ2015
CombinationWeighted Average検出器の重みでスコアを平均化する単純組み合わせ2015
CombinationMaximization最大スコアを取る単純組み合わせ2015
CombinationAOM最大値の平均2015
CombinationMOA平均の最大化2015
CombinationMedianスコアの中央値を取る単純組み合わせ2015
CombinationMajority 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リポジトリ公式ドキュメントを参考に、さらに便利な使い方を調べてみてください。今回の内容を活用して、皆さまのデータ分析や機械学習のプロジェクトに新たな価値をもたらす一助となれば幸いです。