Translate

2022年2月10日木曜日

手っ取り早く異常検知をAIでためす方法としてPyCaretのチュートリアルAO101を翻訳してみた

 異常検知を行うAIを、誰でもかんたんに手っ取り早く実装したい。しかもOSS(ただ)で。

 という、わがままボディな要求があり、そんなものあるわけねえだろ..とおもって調べてみると..見つかった。

PyCaret というPythonパッケージだ。

PyCaret Home: https://pycaret.org/ 


どうもKaggle界では有名なAutoMLパッケージの一つで、極小の手数で複数のモデルを一気に並行評価でき、しかも(AutoMLなので)ハイパーパラメータまで勝手にチューニングしてくれるという..

 kaggleでPyCaretを使っても成績上位にはならないのだけど、どうも就職活動生は人事がわからないだろうことを見越して、「Kaggleに参加している」「成績は上位ではないが、(PyCaretを使って)12のモデルを評価してスコアを出した」とかいってごまかす定番のツールで、これを知ってる知ってないでIT企業人事部の民度が学生にバレるのだという、恐ろしや..

 

とはいえ、機械学習の勉強をあまりしなくても使えるほど、実装のための手数が少ないので、このPyCaretをためすことにした。

 

おあつらえ向きにPyCaretチュートリアルに異常検知に関するチュートリアルがあったので翻訳してみた。

以下、翻訳文であるが、参照の際は At your own riskでお願いします。

-----

異常検知チュートリアル AN0101(Anomaly Detection Tutorial ANO101) - レベル初級

  • PyCaret 2.2を使用
  • 更新日 2020年11月25日

1.0 チュートリアルの目的


異常検知チュートリアル(ANO101) へようこそ。
このチュートリアルは、あなたがPyCaretの初心者で、`pycaret.anomaly` モジュールを使って異常検知を始めようとしていることを想定しています。


このチュートリアルでは、以下のことを学びます:

  • データの取得 :PyCaret リポジトリからデータをインポートするには?
  • 環境のセットアップ :PyCaret で実験環境をセットアップして異常検知モデルの構築を始めるには?
  • モデルの作成 :モデルを作成し、分析に必要なアノマリーラベルを元のデータセットに割り当てるには?
  • モデルのプロット :様々なプロットを使ってモデルの性能を分析する方法
  • モデルによる予測 :学習されたモデルに基づいて、新しいデータセットや未知のデータセットに異常ラベルを割り当てる方法。
  • モデルの保存/読込 :モデルを保存する。将来使用するためにモデルを保存/ロードする方法


読了までの時間:約25分

1.1 PyCaret のインストール


PyCaret を使い始めるための最初のステップは、PyCaret をインストールすることです。PyCaret のインストールは簡単で、数分しかかかりません。以下の手順に従ってください。

ローカルの Jupyter Notebook に PyCaret をインストールする。

pip install pycaret

Google ColabまたはAzureノートブックへのPyCaretのインストール


!pip install pycaret

1.2 前提条件


  • Python 3.6 以上
  • PyCaret 2.0 またはそれ以上
  • PyCaret のリポジトリからデータを読み込むためのインターネット接続環境
  • 異常検知の基礎知識

1.3 Google Colaboratory 使用者への追記


Google Colabで実行している場合、インタラクティブなビジュアルを表示するために、以下のコードをノートブックの先頭で実行してください。

from pycaret.utils import enable_colab
enable_colab()

1.4 参考

Anomaly Detectiom Tutorial (ANO102) - Level Intermediate

https://github.com/pycaret/pycaret/blob/master/tutorials/Anomaly%20Detection%20Tutorial%20Level%20Intermediate%20-%20ANO102.ipynb

Anomaly Detection Tutorial (ANO103) - Level Expert

https://github.com/pycaret/pycaret/blob/master/tutorials/Anomaly%20Detection%20Tutorial%20Level%20Expert%20-%20ANO103.ipynb

訳者注:2022年2月10日時点での上記リンク先はともに未作成。

2.0 異常検知とは?


異常検知とは、データの大部分と大きく異なることによって疑いを抱かせるような、稀な項目、イベント、または観察を特定するタスクをさします。
通常、異常な項目は、銀行詐欺、構造的欠陥、医療問題、テキストの誤りなど、何らかの問題に変換されます。
異常検知技術には大きく分けて3つのカテゴリが存在します。

  • 教師なし異常検知 :ラベル付けされていないテストデータセットから、データセット内の大部分のインスタンスが正常であるという仮定のもと、残りのデータセットに最も適合しないと思われるインスタンスを探し、異常を検出する技術。
  • 教師あり異常検出 :この手法では、「正常」と「異常」のラベルが付けられたデータセットが必要で、分類器を学習させる。
  • 半教師付き異常検知:与えられた正常な学習データセットから正常な振る舞いを表すモデルを構築し、学習したモデルによって生成されるテストインスタンスの尤度をテストする手法です。


`pycaret.anomaly` モジュールは教師なしおよび教師ありの異常検知技術をサポートします。このチュートリアルでは、教師なし異常検知技術のみを取り上げます。

3.0 PyCaret 異常検知モジュール概要


PyCaret 異常検知モジュール `pycaret.anomaly` は、教師なし機械学習モジュールで、データの大部分と大きく異なることによって疑いを持たれるような、稀な項目、イベント、観測を識別するタスクを実行します。

PyCaret 異常検知モジュールは、`setup()` 関数でセットアップを初期化する際に設定できるいくつかの前処理機能を提供します。
12以上のアルゴリズムと、異常検知の結果を分析するためのいくつかのプロットを備えています。
また、PyCaret の異常検知モジュールには `tune_model()` というユニークな関数が実装されており、分類のための `AUC` や回帰のための `R2` など、教師あり学習の目的を最適化するために異常検知モデルのハイパーパラメータを調整することが可能です。

4.0 チュートリアル用データセット


このチュートリアルでは、UCI の Mice Protein Expression というデータセットを使用します。
このデータセットは、大脳皮質の核画分に検出可能なシグナルを生成した77個のタンパク質/タンパク質修飾の発現レベルから構成されています。
このデータセットには、1つのタンパク質につき合計1080の測定値が含まれています。
各測定値は、独立したサンプル/マウスとみなすことができます。
データセットの詳細については、こちらをご覧ください。

データセットへの謝辞

  • Clara Higuera インフォマティクス学部ソフトウェア工学・人工知能学科、コンプルテンセ大学化学部生化学・分子生物学科、スペイン、マドリッド( mailto:clarahiguera@ucm.es )
  • Katheleen J. Gardiner、タンパク質発現データの作成者および所有者は、現在Linda Crnic Institute for Down Syndrome, Department of Pediatrics, Department of Biochemistry and Molecular Genetics, Human Medical Genetics and Genomics, and Neuroscience Programs, University of Colorado, School of Medicine, Aurora, Colorado, USAに在籍( mailto:katheleen.gardiner@ucdenver.edu)
  • Krzysztof J. Ciosは現在、米国バージニア州リッチモンドのバージニア・コモンウェルス大学コンピューターサイエンス学部、およびポーランドのIITiSポーランド科学アカデミーに在籍。( mailto:kcios@vcu.edu )


オリジナルのデータセットとデータディクショナリーは、ここで参照可能。

5.0 データの取得


データをダウンロードし、`pandas` を使って読み込むか、PyCaret のデータレスポジトリを使って `get_data()` 関数で読み込むことができます(インターネット接続が必要)。

from pycaret.datasets import get_data
dataset = get_data('mice')


未見データに対する `predict_model()` 関数のデモを行うため、実験終了時にオリジナルデータセットから5%のサンプル(54サンプル)を取り出し、予測に使用します。
これは、train/test の分割と混同しないように注意する必要があります。
この特別な分割は、実生活のシナリオをシミュレートするために行われます。
別の見方をすれば、この 54 個のサンプルは、この実験が行われた時点では利用できません。

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))

6.0 PyCaretの環境設定


`setup()` 関数は、PyCaret の環境を初期化し、モデリングとデプロイのためのデータを準備する変換パイプラインを作成します。
`setup()` は PyCaret の他の関数を実行する前に呼び出す必要があります。
この関数は 1 つの必須パラメータである pandas dataframe を受け取ります。
他のパラメータはオプションで、前処理パイプラインをカスタマイズするために使用されます(後のチュートリアルで紹介します)。

`setup()` が実行されると、PyCaret の推論アルゴリズムが、特定のプロパティに基づいて全ての特徴のデータ型を自動的に推論します。
しかし、ほとんどの場合、データ型は正しく推論されますが、常にそうとは限りません。
そのため、`setup()`が実行された後、PyCaret は素性とその推定されたデータ型を含むテーブルを表示します。
この段階で、すべてのデータ型が正しく推論されているかどうかを確認し、Enter キーを押して実験を続行するか、 quit キーを押して実験を終了することができます。
PyCaret は、機械学習実験を行うために必要ないくつかの前処理を自動的に行うため、データ型 を正しく特定することは基本的に重要です。
これらの前処理タスクは、データ型ごとに異なる方法で実行されます。
そのため、データ型が正しく設定されていることが非常に重要です。

後のチュートリアルでは、`setup()` の `numeric_features` と `categorical_features` パラメータを使って PyCaret が推論したデータ型を上書きする方法を学びます。

from pycaret.anomaly import *

exp_ano101 = setup(data, normalize = True,
                   ignore_features = ['MouseID'],
                   session_id = 123)


セットアップが正常に実行されると、いくつかの重要な情報を含むグリッドが表示されます。
情報の多くは `setup()` 実行時に構築される事前処理パイプラインに関連するものです。
これらの機能の多くは、このチュートリアルの目的からは外れています。
しかし、この段階で注意すべきいくつかの重要なことがあります。

  • セッションID session_id :後々の再現性のために、すべての関数でシードとして配布される擬似乱数。`session_id` が渡されない場合、乱数は自動的に生成され、すべての関数に配布されます。本実験では、後日の再現性を考慮して、`session_id` を `123` としています。 
  • 欠測値:元データに欠損値がある場合、 `True` と表示されます。上の情報グリッドで欠損値が `True` になっているのは、データに欠損値が含まれているためで、数値特徴の場合は平均値、カテゴリー特徴の場合は定数を用いて自動的にインプットされます。代入(インピュテーション)方法は `setup()` の `numeric_imputation` と `categorical_imputation` パラメータで変更することができます。
  • オリジナルデータ:データセットの元の形状を表示します。本実験では、`(1026, 82)` で、 1026 個のサンプルと 82 個の特徴を意味しています。
  • 変換後データ :変換後のデータセットが表示されます。元のデータセット `(1026, 82)` の形状が `(1026, 91)` に変換されていることに注意してください。データセットにカテゴリ特徴(後述)が含まれているため、特徴の数が増えています。
  • 数値特徴量 :数値として推定された特徴量の数。本データセットでは、82 特徴中77特徴が数値として推定されました。
  • カテゴリ特徴量 :カテゴリ(分類)として推定された特徴の数。本データセットでは、82特徴中5特徴がカテゴリとして推論されました。また、`ignore_feature` パラメータを用いて、1つのカテゴリ特徴である `MouseID` を無視していることに注目してください。


このように、欠損値の代入(インピュテーション)やカテゴリカルエンコーディングなど、モデリングを行う上で必須となるいくつかのタスクが自動的に処理されることに注目してください。
`setup()` の他のパラメータのほとんどはオプションであり、前処理パイプラインをカスタマイズするために使用されます。
これらのパラメータはこのチュートリアルの対象外ですが、中級者、上級者になれば、もっと詳しく説明する予定です。

7.0 モデルの作成


PyCaret で異常検知モデルを作成するのは簡単で、PyCaret の supervised モジュールでモデルを作成する方法と似ています。
異常検知モデルは `create_model()` 関数を用いて作成します。
この関数では、モデルの名前という必須パラメータを文字列で受け取ります。
この関数は学習済みのモデルオブジェクトを返します。
以下の例をご覧ください:

iforest = create_model('iforest')
print(iforest)


`create_model()` で Isolation Forest モデル を作成しました。
`contamination` (混成)パラメータは `0.05` に設定されていますが、これは `create_model()` で `fraction` (割合)パラメータを渡さない場合のデフォルト値です。
`fraction` パラメータはデータセット中の外れ値の割合を決定します。
以下の例では、`0.025` の割合で1クラスサポートベクターマシンモデルを作成します。

svm = create_model('svm', fraction = 0.025)
print(svm)


`create_model()` の引数を `iforest` から `svm` に置き換えるだけで、1クラスサポートベクターマシンモデル(OCSVM)の異常検知モデルを作成することができました。
`pycaret.anomaly`モジュールでは12のモデルが用意されています。
完全なリストを見るには、`docstring` を見るか、`models` 関数を使用してください。

models()

8.0 モデルの割り当て


モデルを作成したので、データセット(1080サンプル)に異常ラベルを付与し、結果を分析したいと思います。
これを実現するには、`assign_model()` 関数を使用します。

以下の例をご覧ください:

iforest_results = assign_model(iforest)
iforest_results.head()


`Anomary` と `Anomary_Score` の2列が最後に追加されていることに注目してください。
`Anomary` 値 `0` は範囲内の値、`1` は孤立値/Anomalyを表します。
`Anomary_Score` はアルゴリズムによって計算された値で、外れ値にはより大きな異常値スコアが割り当てられます。

`iforest_results` には、`setup()` で削除した `MouseID` 特徴も含まれていることに注意してください。
これはモデルには使用されず、`assign_model()` を使用したときのみデータセットに追加されます。
次のセクションでは、`plot_model()` を使って異常検知の結果を分析する方法を見ていきます。

9.0 モデルのプロット


`plot_model()` 関数は、異常検知モデルを様々な角度から分析するために使用することができます。
この関数は,学習済みモデルオブジェクトを受け取り、プロットを返します。
以下の例を参照してください:

9.1 T分散確率的近傍埋込み法(t-SNE)

plot_model(iforest)



9.2 一様多様体近似と射影

plot_model(iforest, plot = 'umap')

METADATAファイルがないというエラーが出たが..パッケージ導入ミス?!

10.0 未知データに対する予測


`predict_model()` 関数は、新しい未閲覧のデータセットに異常ラベルを割り当てるために使用されます。
ここでは、`data_unseen` に格納されたデータを予測するために `iforest` モデルを使用します。
これは実験の最初に作成されたもので、これまでPyCaretに公開されていなかった54個の新しいサンプルが含まれています。

unseen_predictions = predict_model(iforest, data=data_unseen)
unseen_predictions.head()


`Anomary` 欄は外れ値(1=外れ値、0=非外れ値)を示しています。
`Anomary_Score` 欄はアルゴリズムによって計算された値で、外れ値にはより大きな異常値スコアが割り当てられます。
`predict_model()` 関数を使用して、学習データにラベルを付けることもできます。
以下の例を参照してください:

data_predictions = predict_model(iforest, data = data)
data_predictions.head()

11.0 モデルの保存


ここまでのチュートリアルでは、`iforest` モデルを使って未見データの外れ値ラベルを予測する実験が終了しました。
これで実験は終わりですが、まだ一つの疑問が残っています。
予測すべき新しいデータが増えたらどうなるのだろうか?
もう一度、この実験をやり直さなければならないのだろうか?
答えは「いいえ」です。

実験全体を再実行し、新しいデータに対して予測を生成するためにパイプラインを再構築する必要はありません。PyCaret の組み込み関数 `save_model()` は、変換パイプライン全体と共にモデルを保存し、再利用することができます。

save_model(iforest,'Final IForest Model 25Nov2020')

12.0 保存されたモデルのロード


保存したモデルを将来同じ環境または異なる環境でロードするには、PyCaret の `load_model()` 関数を使用し、保存したモデルを新しい未知のデータに簡単に適用して予測します。

saved_iforest = load_model('Final IForest Model 25Nov2020')

一旦モデルが環境にロードされると、同じ `predict_model()` 関数を使用して新しいデータに対して予測するためにそれを単純に使用することができます。
以下では、上記のセクション10で使用したのと同じ `data_unseen` を予測するために、ロードされたモデルを適用しています:

new_prediction = predict_model(saved_iforest, data=data_unseen)
new_prediction.head()

`unseen_prediction` と `new_prediction` の結果は同じであることに注意してください。

13.0 まとめ/次のステップへ?


このチュートリアルでは、`pycaret.anomaly` の基本的な部分のみを取り上げました。
次のチュートリアルでは、データサイエンティストなら必ず知っておくべき、機械学習パイプラインを完全にカスタマイズできる高度な前処理技術に深入りしていきます。

それでは、次回のチュートリアルでお会いしましょう。Anomaly Detection Tutorial (ANO102) - Level Intermediate へのリンクをたどってください。

------

AO102以降のリンクは、本記事執筆時点では未作成だった。

上記チュートリアルには教師なし学習でのクラスタリングしか書かれていないが、分類についても別のチュートリアル(異常検知データセットではないが)があるので、すぐに理解できると思う。

AutoMLか..むかし昭和一桁の親父が安物カメラをくれたとき、「バカ○○○だからだれでも使えるぞ」といっていたが、AutoMLがまさにそうだ。

情報という科目はAIやデータ分析のちからを養うために入試化されるそうだけど、使うほうがどんどん簡単になるので、なくてもいいかもなあ...



AWS Glueジョブ(Python/Spark)にPythonパッケージを追加する方法

 AWS Glueジョブには2つの種類が存在します。 ETLジョブ(Spark) PySparkコードが実行できるジョブ。 最低でも10並列で実行するので、DynamicFrame/DataFrame操作以外の処理はPython Shellジョブを使ったほうがよい。 Python...