Udemyで異常検知のコースを開設しました。実装方法を分かり易く具体的に短時間のコースにまとめましたので活用ください。
異常を検出する、と一言で言っても本来は難しい仕事です。
「異常」の状態は様々で、想像もできないことがあるからです。
例えば異常気象、機械の故障、人の病気は、既に知っている異常ならば学習して検出することができます。異常の記録や画像をディープラーニングで学習し、以後のチェックを行うといった形です。
では、知らない故障や病気は検知することができないのでしょうか。
方法があります。ディープラーニングで可能です。
異常検知の考え方
ずばり、いつもと違う事象を検知するという方法です。
異常な状態が定義できないのなら、通常の状態を定義しておき、それ以外は全て検知してしまうという考え方です。アノマリー(普通でない)検知とも言います。
ディープラーニングで通常の状態を学習し、通常でない状態が来たら判別するという仕組みを利用します。
これには、AutoEncoder というディープラーニングのモデルが適します。AutoEncoder はデータの特徴を捉えることに特化したモデルだからです。
AutoEncoder
AutoEncoderを抽象化したのが下図です。
同じ種類で統一したデータを入力し、出力として同一のデータを生成させます。データは画像、音声、ログなどでも構いません。
AutoEncoderの内部ではデータを圧縮しており、これにより多くのデータに共通した特徴をとらえることができます。
こうして学習したAutoEncoderに新しいデータを入力した時、学習時と似ているデータであれば生成が可能であるし、差が大きなデータであれば生成結果が良くないことになります。
生成結果を数値化して正常/異常と判断するのが異常検知の仕組みです。
プログラムとデータ
環境の準備がまだの人は、この記事を参照して準備してください。
それでは実際にAutoEncoderプログラムを動かしてみましょう。
難しい解説は省きます。コメントを参照して大きな流れだけ理解してください。
メモ帳を開き、下のプログラムをコピペし、ファイル名を「ae_anomaly.py」として保存してください。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 |
import numpy as np import pandas as pd import keras.models from keras.models import Model from keras.layers import Input, Dense, BatchNormalization, Activation from keras.models import Sequential # 入力データのカラム数 INPUT_SIZE = 16 # 学習データの読み込み train_data = pd.read_csv('train_data.csv') # AutoEncoderモデルの組み立て model = Sequential() model.add(Dense(INPUT_SIZE,input_shape=(INPUT_SIZE,))) model.add(BatchNormalization()) model.add(Activation('relu')) model.add(Dense(int(np.sqrt(INPUT_SIZE)))) model.add(BatchNormalization()) model.add(Activation('relu')) model.add(Dense(INPUT_SIZE)) model.add(BatchNormalization()) model.add(Activation('relu')) model.add(Dense(INPUT_SIZE)) model.compile(optimizer='adam', loss='mean_squared_error') # 学習:入力データと結果データを同一にする history = model.fit(x=train_data, y=train_data, epochs=100, batch_size=2, validation_split=0.1) # 予測:テストデータを読み込んで異常かどうか判別 test_data = pd.read_csv('test_data.csv', header=None) test_pred = model.predict(test_data) test_score = np.mean(np.square(test_data - test_pred), axis=1) print('Data Flag') print(test_score) |
下は学習用データです。同じくコピペしてファイル名「train_data.csv」で保存してください。
この内容は何の意味もない数字の羅列ですが、「通常」を表すために、できるだけ近い数値で少し変化をつけています。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 |
5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,6,6,6,7,7,8,7,7,6,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,5,6,6,7,8,8,7,6,6,6,5,5,5,5 5,5,6,6,6,6,7,7,8,7,7,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,6,6,6,7,7,8,7,7,6,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,5,6,6,7,8,8,7,6,6,6,5,5,5,5 5,5,6,6,6,6,7,7,8,7,7,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,6,6,6,7,7,8,7,7,6,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,5,6,6,7,8,8,7,6,6,6,5,5,5,5 5,5,6,6,6,6,7,7,8,7,7,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,6,6,6,7,7,8,7,7,6,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,5,6,6,7,8,8,7,6,6,6,5,5,5,5 5,5,6,6,6,6,7,7,8,7,7,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,6,6,6,7,7,8,7,7,6,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,5,6,6,7,8,8,7,6,6,6,5,5,5,5 5,5,6,6,6,6,7,7,8,7,7,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,6,6,6,7,7,8,7,7,6,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,5,6,6,7,8,8,7,6,6,6,5,5,5,5 5,5,6,6,6,6,7,7,8,7,7,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,6,6,6,7,7,8,7,7,6,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,5,6,6,7,8,8,7,6,6,6,5,5,5,5 5,5,6,6,6,6,7,7,8,7,7,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,6,6,6,7,7,8,7,7,6,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,5,6,6,7,8,8,7,6,6,6,5,5,5,5 5,5,6,6,6,6,7,7,8,7,7,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,6,6,6,7,7,8,7,7,6,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,5,6,6,7,8,8,7,6,6,6,5,5,5,5 5,5,6,6,6,6,7,7,8,7,7,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,6,6,6,7,7,8,7,7,6,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,5,6,6,7,8,8,7,6,6,6,5,5,5,5 5,5,6,6,6,6,7,7,8,7,7,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,6,6,6,7,7,8,7,7,6,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,5,6,6,7,8,8,7,6,6,6,5,5,5,5 5,5,6,6,6,6,7,7,8,7,7,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,6,6,6,7,7,8,7,7,6,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,5,6,6,7,8,8,7,6,6,6,5,5,5,5 5,5,6,6,6,6,7,7,8,7,7,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,6,6,6,7,7,8,7,7,6,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,5,6,6,7,8,8,7,6,6,6,5,5,5,5 5,5,6,6,6,6,7,7,8,7,7,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,6,6,6,7,7,8,7,7,6,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,5,6,6,7,8,8,7,6,6,6,5,5,5,5 5,5,6,6,6,6,7,7,8,7,7,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,6,6,6,7,7,8,7,7,6,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,5,6,6,7,8,8,7,6,6,6,5,5,5,5 5,5,6,6,6,6,7,7,8,7,7,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,6,6,6,7,7,8,7,7,6,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,5,6,6,7,8,8,7,6,6,6,5,5,5,5 5,5,6,6,6,6,7,7,8,7,7,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,6,6,6,7,7,8,7,7,6,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,5,6,6,7,8,8,7,6,6,6,5,5,5,5 5,5,6,6,6,6,7,7,8,7,7,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,6,6,6,7,7,8,7,7,6,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,5,6,6,7,8,8,7,6,6,6,5,5,5,5 5,5,6,6,6,6,7,7,8,7,7,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,6,6,6,7,7,8,7,7,6,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,5,6,6,7,8,8,7,6,6,6,5,5,5,5 5,5,6,6,6,6,7,7,8,7,7,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,6,6,6,7,7,8,7,7,6,6,6,5,5,5 5,5,5,6,6,6,6,7,7,6,6,6,5,5,5,5 5,5,5,6,6,7,8,8,7,6,6,6,5,5,5,5 5,5,6,6,6,6,7,7,8,7,7,6,6,5,5,5 |
下は予測用データです。同じくコピペしてファイル名「test_data.csv」で保存してください。
1行目のデータはできるだけ学習用データに近いものを、2行目のデータは通常より高めの数値にしてあり「異常」を表しています。
1 2 |
5,5,5,6,6,7,8,8,7,6,6,6,5,5,5,5 5,5,6,6,7,7,8,9,10,9,8,7,6,6,5,5 |
実行
PCの環境準備がまだの人はこちらを実施してください。 AIを作ってみよう:環境の準備から
プログラムとデータが保存できたら、下記のように実行します。
- コマンド入力ウィンドウを開きます。
Windowsの場合:スタートボタンを押す → メニューが出たらそのまま「cmd」と打ち「Enter」。
Macintoshの場合:「ターミナル」を実行します。
- 3ファイルを保存した場所に移動します。デスクトップであれば
Win,Macどちらも「cd desktop」と打ち「Enter」です。
- AIの学習を実行します。
「python ae_anomaly.py」と打ち「Enter」。
- 学習用データを読み込み、学習が始まります。30秒程度待ちます。
- そのままテストデータで予測をし結果が出ます。
Data Flag
0 0.*** ← 1つ目のデータは正常を示す小さい値となります
1 ***** ← 2つ目のデータは異常を示す大きな値となります
いかがでしょうか。異常なデータに対して異常値が出たでしょうか。
異常検知をできるだけ簡単に具体化してみました。
このプログラムは汎用的で、これを骨格としてカスタマイズし様々な仕事に応用できると思います。
今回は数値ログで試しましたが、画像や音声といったデータでも異常検知が可能です。その場合は入力データサイズを大きくするなどの調整が必要です。
通常でない事象を全てチェックするという仕組みは、異常な状態が分からない場合に有用ですから、覚えておいて損はありません。