ADTK (異常検知ツールキット) 0.6 : Examples : Detector (翻訳/解説)
翻訳 : (株)クラスキャット セールスインフォメーション
作成日時 : 06/22/2021 (0.6.2)
* 本ページは、ADTK の以下のページの Detector セクションを翻訳した上で適宜、補足説明したものです:
* サンプルコードの動作確認はしておりますが、必要な場合には適宜、追加改変しています。
* ご自由にリンクを張って頂いてかまいませんが、sales-info@classcat.com までご一報いただけると嬉しいです。
スケジュールは弊社 公式 Web サイト でご確認頂けます。
- お住まいの地域に関係なく Web ブラウザからご参加頂けます。事前登録 が必要ですのでご注意ください。
- ウェビナー運用には弊社製品「ClassCat® Webinar」を利用しています。
人工知能研究開発支援 | 人工知能研修サービス | テレワーク & オンライン授業を支援 |
PoC(概念実証)を失敗させないための支援 (本支援はセミナーに参加しアンケートに回答した方を対象としています。) |
◆ お問合せ : 本件に関するお問い合わせ先は下記までお願いいたします。
株式会社クラスキャット セールス・マーケティング本部 セールス・インフォメーション |
E-Mail:sales-info@classcat.com ; WebSite: https://www.classcat.com/ ; Facebook |
ADTK (異常検知ツールキット) 0.6 : Examples : Detector
概要
- ThresholdAD – 各時系列値を与えられた閾値と比較します。
- QuantileAD – 各時系列値を履歴 quantiles (分位点、変位値) と比較します。
例えば、気温が 99% パーセンタイルより上か 1% パーセンタイルより下であるとき時間ポイントを検知します。
- InterQuartileRangeAD – 単純な履歴統計に基づくもう一つの広く利用される detector で、四分位範囲 (IQR, interquartile range) に基づきます。
- GeneralizedESDTestAD – generalized extreme Studentized deviate (ESD) に基づいて異常を検知します。
※ generalized ESD テストのキーとなる仮定は正常値は近似的に正規分布に従うことであることに注意してください。
- PersistAD – 各時系列値をその前の値と比較します。
※ デフォルトでは PersistAD は一つ前の値をチェックするだけです、これは短期間スケールで additive 異常を捕捉するには良いですが、長期間スケールではそうではありません、何故ならばそれは近視眼的に過ぎるからです。
- LevelShiftAD – 隣同士の 2 つのスライディング時間ウィンドウにおける median 値の間の差を追跡する ことにより値レベルのシフトを検知します。
- VolatilityShiftAD – volatility (変動性) レベルのシフトを隣り合う 2 つのスライディング時間ウィンドウにおける 標準偏差間の差異を追跡する ことにより検知します。
- SeasonalAD – seasonal パターンの異常 vaiolation を検知します。
- AutoregressionAD – 時系列の自己回帰の異常な変化を検知します。
- MinClusterDetector – 多変量 時系列を高次元空間の独立したポイントとして扱い、それらをクラスタに分割し、そして最も小さいクラスタの値を異常として識別します。これは高次元空間の外れ値を捕捉するのに役立つかも知れません。
- OutlierDetector – 多変量 時間独立な外れ値検知を遂行して外れ値を異常として識別します。多変量外れ値検知アルゴリズムは同じ API に従う scikit-learn or 他のパッケージのそれらであり得ます。scikit-learn local outlier factor model とともに OutlierDetector を適用できます。
- RegressionAD – regressive error を追跡することにより 多変量 系列間の通常の関係の異常な violation を検知します。線形回帰モデルとともに RegressionAD を適用できます。
- PcaAD – 主成分分析 (PCA) を 多変量 時系列 (高次元空間のベクトルとして総ての時間ポイント) に遂行してそれらのベクトルの reconstruction error を追跡します。
- CustomizedDetector – CustomizedDetector1D と CustomizedDetectorHD はユーザに関数を他の detector オブジェクトとして (Pipeline オブジェクトにより、例えば) 利用できるようなカスタマイズされた detector オブジェクトに変換するために役立ちます。
ThresholdAD
ThresholdAD は各時系列値を与えられた閾値と比較します。
次の例では、気温が 30C より上か 15C より下であるとき時間ポイントを検知します。
import pandas as pd
s = pd.read_csv('./data/temperature.csv', index_col="Time", parse_dates=True, squeeze=True)
from adtk.data import validate_series
s = validate_series(s)
Time 2017-05-02 00:00:00 18.91 2017-05-02 01:00:00 19.91 2017-05-02 02:00:00 20.19 2017-05-02 03:00:00 18.69 2017-05-02 04:00:00 18.11 ... 2017-05-10 03:00:00 21.70 2017-05-10 04:00:00 21.43 2017-05-10 05:00:00 21.32 2017-05-10 06:00:00 20.98 2017-05-10 07:00:00 20.76 Freq: H, Name: Temperature (C), Length: 200, dtype: float64
from adtk.detector import ThresholdAD
threshold_ad = ThresholdAD(high=30, low=15)
anomalies = threshold_ad.detect(s)
Time 2017-05-02 00:00:00 False 2017-05-02 01:00:00 False 2017-05-02 02:00:00 False 2017-05-02 03:00:00 False 2017-05-02 04:00:00 False ... 2017-05-10 03:00:00 False 2017-05-10 04:00:00 False 2017-05-10 05:00:00 False 2017-05-10 06:00:00 False 2017-05-10 07:00:00 False Freq: H, Name: Temperature (C), Length: 200, dtype: bool
from adtk.visualization import plot
plot(s, anomaly=anomalies, ts_linewidth=1, ts_markersize=3, anomaly_markersize=5, anomaly_color='red', anomaly_tag="marker");
QuantileAD
QuantileAD は各時系列値を履歴 quantiles (分位点、変位値) と比較します。
次の例では、気温が 99% パーセンタイルより上か 1% パーセンタイルより下であるとき時間ポイントを検知します。
from adtk.detector import QuantileAD
quantile_ad = QuantileAD(high=0.99, low=0.01)
anomalies = quantile_ad.fit_detect(s)
Time 2017-05-02 00:00:00 False 2017-05-02 01:00:00 False 2017-05-02 02:00:00 False 2017-05-02 03:00:00 False 2017-05-02 04:00:00 False ... 2017-05-10 03:00:00 False 2017-05-10 04:00:00 False 2017-05-10 05:00:00 False 2017-05-10 06:00:00 False 2017-05-10 07:00:00 False Freq: H, Name: Temperature (C), Length: 200, dtype: bool
plot(s, anomaly=anomalies, ts_linewidth=1, ts_markersize=3, anomaly_markersize=5, anomaly_color='red', anomaly_tag="marker");
InterQuartileRangeAD
InterQuartileRangeAD は単純な履歴統計に基づくもう一つの広く利用される detector で四分位範囲 (IQR, interquartile range) に基づきます。When a value is out of the range defined by [Q_1 – c \times IQR,\ Q_3 + c \times IQR] where IQR = Q_3 – Q_1 is the difference between 25% and 75% quantiles. この detector は訓練データの小さな部分が異常であるか異常が全くない場合には通常は QuantileAD よりも選択されます。
from adtk.detector import InterQuartileRangeAD
iqr_ad = InterQuartileRangeAD(c=1.5)
anomalies = iqr_ad.fit_detect(s)
plot(s, anomaly=anomalies, ts_linewidth=1, ts_markersize=3, anomaly_markersize=5, anomaly_color='red', anomaly_tag="marker");
GeneralizedESDTestAD
GeneralizedESDTestAD は generalized extreme Studentized deviate (ESD) に基づいて異常を検知します。
generalized ESD テストのキーとなる仮定は正常値は近似的に正規分布に従うことであることに注意してください。この仮定が有効であるときだけにこの detector を利用してください。
from adtk.detector import GeneralizedESDTestAD
esd_ad = GeneralizedESDTestAD(alpha=0.3)
anomalies = esd_ad.fit_detect(s)
plot(s, anomaly=anomalies, ts_linewidth=1, ts_markersize=3, anomaly_markersize=5, anomaly_color='red', anomaly_tag="marker");
PersistAD
PersistAD は各時系列値をその前の値と比較します。内部的には、それは transformer DoubleRollingAggregate を伴う pipenet として実装されます。
以下の例では、価格の異常な positive 変化を検知します。
s = pd.read_csv('./data/price_short.csv', index_col="Time", parse_dates=True, squeeze=True)
s = validate_series(s)
Time 2017-05-02 00:00:00 21.33 2017-05-02 01:00:00 22.05 2017-05-02 02:00:00 20.50 2017-05-02 03:00:00 20.49 2017-05-02 04:00:00 21.11 ... 2017-05-10 03:00:00 49.34 2017-05-10 04:00:00 50.29 2017-05-10 05:00:00 49.27 2017-05-10 06:00:00 50.43 2017-05-10 07:00:00 49.86 Freq: H, Name: Price ($), Length: 200, dtype: float64
from adtk.detector import PersistAD
persist_ad = PersistAD(c=3.0, side='positive')
anomalies = persist_ad.fit_detect(s)
plot(s, anomaly=anomalies, ts_linewidth=1, ts_markersize=3, anomaly_color='red');
デフォルトでは、PersistAD は一つ前の値をチェックするだけです、これは短期間スケールで additive 異常を捕捉するには良いですが、長期間スケールではそうではありません、何故ならばそれは近視眼的に過ぎるからです。
次の例では、より長いタイムスケールで価格の meaningful 下落を捕捉することに失敗しています。
s = pd.read_csv('./data/price_long.csv', index_col="Time", parse_dates=True, squeeze=True)
s = validate_series(s)
Time 2017-05-02 00:00:00 21.33 2017-05-02 01:00:00 22.05 2017-05-02 02:00:00 20.50 2017-05-02 03:00:00 20.49 2017-05-02 04:00:00 21.11 ... 2017-06-12 11:00:00 4.08 2017-06-12 12:00:00 3.75 2017-06-12 13:00:00 5.19 2017-06-12 14:00:00 4.80 2017-06-12 15:00:00 5.44 Freq: H, Name: Price ($), Length: 1000, dtype: float64
persist_ad = PersistAD(c=1.5, side='negative')
anomalies = persist_ad.fit_detect(s)
plot(s, anomaly=anomalies, anomaly_color='red');
パラメータウィンドウを 1 より大きい数字に変更しても良いです、すると detector は値を前の時間ウィンドウの中央値か平均と値を比較します。それは近視眼的ではあまりないので、これは中期から長期スケールでの異常変化を捕捉します。上と同じサンプルで、それは長期スケールで価格の下落を成功的に検出しています。
persist_ad.window = 24
anomalies = persist_ad.fit_detect(s)
plot(s, anomaly=anomalies, anomaly_color='red');
LevelShiftAD
LevelShiftAD は隣同士の 2 つのスライディング時間ウィンドウにおける median 値の間の差を追跡することにより値レベルのシフトを検知します。それは瞬間的なスパイクには敏感ではなく、ノイズの多い外れ値が頻繁に発生する場合には良い選択である可能性があります。内部的には、それは transformer DoubleRollingAggregate を伴う pipenet として実装されます。
次のサンプルでは、CPU 使用率のシフトポイントを検知します。
s = pd.read_csv('./data/cpu.csv', index_col="Time", parse_dates=True, squeeze=True)
s = validate_series(s)
Time 2017-05-02 00:00:00 19.597904 2017-05-02 01:00:00 18.858335 2017-05-02 02:00:00 16.145520 2017-05-02 03:00:00 17.989939 2017-05-02 04:00:00 18.745603 ... 2017-06-12 11:00:00 16.782793 2017-06-12 12:00:00 17.601807 2017-06-12 13:00:00 19.728837 2017-06-12 14:00:00 17.531739 2017-06-12 15:00:00 18.770941 Freq: H, Name: CPU (%), Length: 1000, dtype: float64
from adtk.detector import LevelShiftAD
level_shift_ad = LevelShiftAD(c=6.0, side='both', window=5)
anomalies = level_shift_ad.fit_detect(s)
plot(s, anomaly=anomalies, anomaly_color='red');
VolatilityShiftAD
VolatilityShiftAD は volatility (変動性) レベルのシフトを隣り合う 2 つのスライディング時間ウィンドウにおける標準偏差間の差異を追跡することにより検知します。内部的には、それは transformer DoubleRollingAggregate を伴う pipenet として実装されます。
次の例では、地震の始まりを示す、地震振幅 (= seismic amplitude) の変動性の positive shift を検知しています。
s = pd.read_csv('./data/seismic.csv', index_col="Time", parse_dates=True, squeeze=True)
s = validate_series(s)
Time 2017-05-02 17:08:37.000 3.994760 2017-05-02 17:08:37.500 2.145837 2017-05-02 17:08:38.000 -4.636201 2017-05-02 17:08:38.500 -0.025152 2017-05-02 17:08:39.000 1.864008 ... 2017-05-02 17:16:54.500 23.206275 2017-05-02 17:16:55.000 -18.304593 2017-05-02 17:16:55.500 4.448594 2017-05-02 17:16:56.000 57.900672 2017-05-02 17:16:56.500 17.283682 Freq: 500L, Name: Seismic amplitude (mm), Length: 1000, dtype: float64
from adtk.detector import VolatilityShiftAD
volatility_shift_ad = VolatilityShiftAD(c=6.0, side='positive', window=30)
anomalies = volatility_shift_ad.fit_detect(s)
plot(s, anomaly=anomalies, anomaly_color='red');
SeasonalAD
SeasonalAD は seasonal パターンの異常 vaiolation を検知します。内部的には、それは transformer ClassicSeasonalDecomposition を伴う pipenet として実装されます。
次の例では、普通ではない交通量を検知します、これは殆どは主要な祝日で発生しました。
s = pd.read_csv('./data/seasonal.csv', index_col="Time", parse_dates=True, squeeze=True)
s = validate_series(s)
Time 2014-07-01 00:00:00 10844 2014-07-01 00:30:00 8127 2014-07-01 01:00:00 6210 2014-07-01 01:30:00 4656 2014-07-01 02:00:00 3820 ... 2015-01-31 21:30:00 24670 2015-01-31 22:00:00 25721 2015-01-31 22:30:00 27309 2015-01-31 23:00:00 26591 2015-01-31 23:30:00 26288
from adtk.detector import SeasonalAD
seasonal_ad = SeasonalAD(c=3.0, side="both")
anomalies = seasonal_ad.fit_detect(s)
plot(s, anomaly=anomalies, ts_markersize=1, anomaly_color='red', anomaly_tag="marker", anomaly_markersize=2);
AutoregressionAD
AutoregressionAD は時系列の自己回帰の異常な変化を検知します。内部的には、それは transformers Retrospect と RegressionResidual を伴う pipenet として実装されます。
上と同じ例について、交通量履歴の普通ではない回帰動作の violatioin を検知します。
s = pd.read_csv('./data/seasonal.csv', index_col="Time", parse_dates=True, squeeze=True)
s = validate_series(s)
from adtk.detector import AutoregressionAD autoregression_ad = AutoregressionAD(n_steps=7*2, step_size=24, c=3.0) anomalies = autoregression_ad.fit_detect(s) plot(s, anomaly=anomalies, ts_markersize=1, anomaly_color='red', anomaly_tag="marker", anomaly_markersize=2);
MinClusterDetector
MinClusterDetector は多変量時系列を高次元空間の独立したポイントとして扱い、それらをクラスタに分割し、そして最も小さいクラスタの値を異常として識別します。これは高次元空間の外れ値を捕捉するのに役立つかも知れません。
次の例は、発電機のスピードと生成されるパワー間の関係の異常な変化を検知します。通常の関係の violation は装置の failure を示します。
f = pd.read_csv('./data/generator.csv', index_col="Time", parse_dates=True, squeeze=True)
df = validate_series(df)
from adtk.detector import MinClusterDetector
from sklearn.cluster import KMeans
min_cluster_detector = MinClusterDetector(KMeans(n_clusters=3))
anomalies = min_cluster_detector.fit_detect(df)
plot(df, anomaly=anomalies, ts_linewidth=1, ts_markersize=3, anomaly_color='red', anomaly_alpha=0.3, curve_group='all');
OutlierDetector
OutlierDetector は多変量時間独立な外れ値検知を遂行して外れ値を異常として識別します。多変量外れ値検知アルゴリズムは同じ API に従う scikit-learn or 他のパッケージのそれらであり得ます。
上と同じ例について、scikit-learn local outlier factor model とともに OutlierDetector を適用します。
from adtk.detector import OutlierDetector
from sklearn.neighbors import LocalOutlierFactor
outlier_detector = OutlierDetector(LocalOutlierFactor(contamination=0.05))
anomalies = outlier_detector.fit_detect(df)
plot(df, anomaly=anomalies, ts_linewidth=1, ts_markersize=3, anomaly_color='red', anomaly_alpha=0.3, curve_group='all');
RegressionAD
RegressionAD は regressive error を追跡することにより多変量系列間の通常の関係の異常な violation を検知します。内部的には、それは transformer RegressionResidual を伴う pipenet として実装されます。
上と同じ例について、線形回帰モデルとともに RegressionAD を適用します。
from adtk.detector import RegressionAD
from sklearn.linear_model import LinearRegression
regression_ad = RegressionAD(regressor=LinearRegression(), target="Speed (kRPM)", c=3.0)
anomalies = regression_ad.fit_detect(df)
plot(df, anomaly=anomalies, ts_linewidth=1, ts_markersize=3, anomaly_color='red', anomaly_alpha=0.3, curve_group='all');
PcaAD
PcaAD は主成分分析 (PCA) を多変量時系列 (高次元空間のベクトルとして総ての時間ポイント) に遂行してそれらのベクトルの reconstruction error を追跡します。この detector は正常ポイントが低ランク manifold にある一方で異常ポイントがそうではないと想定されるときに有用です。内部的には、それは transformer PcaReconstructionError を伴う pipeline として実装されます。
上と同じ例に PcaAD を適用します。
from adtk.detector import PcaAD
pca_ad = PcaAD(k=1)
anomalies = pca_ad.fit_detect(df)
plot(df, anomaly=anomalies, ts_linewidth=1, ts_markersize=3, anomaly_color='red', anomaly_alpha=0.3, curve_group='all');
CustomizedDetector
CustomizedDetector1D と CustomizedDetectorHD はユーザに関数を他の detector オブジェクトとして (Pipeline オブジェクトにより、例えば) 利用できるようなカスタマイズされた detector オブジェクトに変換するために役立ちます。
次の例では、生成された電力 (in kW) が発電機速度 (in kRPM) の 1.2 倍未満であるときを検出します。
df = pd.read_csv('./data/generator.csv', index_col="Time", parse_dates=True)
df = validate_series(df)
df.head()
Speed (kRPM) Power (kW) Time 2017-05-02 17:08:37 6.066579 10.308257 2017-05-02 18:08:37 6.035764 9.186763 2017-05-02 19:08:37 5.922730 10.128382 2017-05-02 20:08:37 5.999581 10.290300 2017-05-02 21:08:37 6.031067 8.910037
def myDetectionFunc(df):
return (df["Speed (kRPM)"] * 1.2 > df["Power (kW)"])
from adtk.detector import CustomizedDetectorHD
customized_detector = CustomizedDetectorHD(detect_func=myDetectionFunc)
anomalies = customized_detector.detect(df)
plot(df, anomaly=anomalies, ts_linewidth=1, ts_markersize=3, anomaly_color='red', anomaly_alpha=0.3, curve_group='all');
以上