JA EN
体系時系列データ系
·★ 会員·論文·13分で読めます

時系列異常検知 — 監視の現場で動いている数学

監視のアラートは、値の大きさではなく「その時刻に期待される値とのずれ」で鳴らすべきです。ロバストな統計量・予測残差・部分列の近傍距離・変化点検出という4つの物差しを比喩から式まで積み上げ、実務で最も事故が多い閾値の決め方と評価の罠まで扱います。

対象textタスクforecasting

Bayesian Online Changepoint Detection


深夜2時、監視画面が赤くなる

CPU使用率が90%を超えたらアラートを鳴らす。監視の第一歩はたいていこれです。そして1ヶ月も運用すると、ほぼ必ずこうなります。毎週日曜の未明に重いバッチが走って90%を超え、当番が叩き起こされる。仕方なく閾値を95%へ上げると、今度は平日の本当の障害が92%で止まっていて、誰も気づかない。

問題は数字ではなく、「異常」を値の大きさだけで定義したことです。日曜未明の90%は正常で、火曜午後の70%のほうが異常かもしれない。時系列の異常とは、値そのものではなくその時刻・その文脈から期待される値とのずれです。この記事では、そのずれを測る物差しを4つ——統計量・予測残差・部分列の距離・変化点——順に組み立てます。前提知識は平均と標準偏差だけで足ります。

「異常」には3つの顔がある

点異常は、単独の値がぽつんと外れるもの。センサの読み取りミスで一瞬だけ 9999 が出る、といったスパイクです。

文脈異常は、値自体はありふれているのにその時刻には起きないはずというもの。真夏に暖房の電力が立つ、深夜3時のアクセス数が昼のピーク並みになる。値の分布としては外れていないので、ヒストグラムを眺めても永遠に見つかりません。

部分列異常は、一つ一つの値は普通なのに並び方がおかしいもの。心電図で一拍だけリズムが崩れる、振動センサの周期が乱れる。各点を独立に見ている限り、これも検知できません。

時系列に固有なのは後ろの2つで、現場で本当に困るのもこの2つです。

物差し1: 統計的な「外れ具合」

古典から始めます。平均からの距離を、標準偏差を単位にして測るzスコアです。

zt=xtμσz_t = \frac{x_t - \mu}{\sigma}
(1)

xtx_t は時刻 tt の観測値、μ\mu は平均、σ\sigma は標準偏差。要するに「平均から標準偏差何個分ぶん離れているか」を数えているだけです。正規分布なら z>3|z| > 3 は約0.3%しか起きないので、そこに線を引く——「3シグマ」と呼ばれる慣行です。

素朴ですが、そのままでは2つの理由で壊れます。

ひとつは異常が自分自身を隠すこと。μ\muσ\sigma は異常を含んだデータから計算されています。巨大なスパイクが1点あると、それが σ\sigma を膨らませ、結果として自分の zz を小さくしてしまう。異常が大きいほど見つけにくいという意地の悪い性質で、マスキングと呼ばれます。対策は、外れ値に引きずられない統計量——中央値とMAD(中央絶対偏差)への置き換えです。

MAD=median(xtmedian(x)),ztrob=xtmedian(x)1.4826MAD\mathrm{MAD} = \mathrm{median}\big(|x_t - \mathrm{median}(x)|\big), \qquad z^{\text{rob}}_t = \frac{x_t - \mathrm{median}(x)}{1.4826 \cdot \mathrm{MAD}}
(2)

要するに「中央値からのずれの、中央値」を散らばりの尺度に使うということです。1.48261.4826 は正規分布のとき σ\sigma と一致させるための定数で、深い意味はありません。中央値は半分近くが汚染されても動かないので、スパイクが何点混ざっても物差しが狂いません。

もうひとつは平均が一定でないこと。トレンドがあれば去年の平均は今日の基準になりませんし、日内周期があれば「1日の平均」は昼にも夜にも当てはまりません。対策は、全期間ではなく直近の窓だけで μ\muσ\sigma を計算することです。製造業の管理図は、この発想で100年近く現場を回してきました。

import numpy as np

def robust_z(x, window=288):                 # 288 = 5分刻みで1日分
    med = np.median(x[-window:])
    mad = np.median(np.abs(x[-window:] - med))
    return (x[-1] - med) / (1.4826 * mad + 1e-9)

窓幅が最初のハイパーパラメータです。短いと敏感になる一方、異常が続くとそれが新しい「正常」になる。長いと鈍く、正当な変化にも延々と鳴り続ける。この綱引きは、以降のどの手法にも形を変えて現れます。

物差し2: 予測して、残差を見る

発想を変えます。「正常なときの系列を予測できるモデル」を先に作り、予測と実測の差(残差)を異常度にするのです。

et=xtx^te_t = x_t - \hat{x}_t
(3)

x^t\hat{x}_t が予測値です。つまり異常検知を、予測問題とその後始末に分解したことになります。

この分解が効くのは、トレンド・季節性・カレンダー効果をまるごとモデル側へ押し込められるからです。冒頭の日曜バッチを思い出してください。予測が「日曜未明は90%」と知っていれば、実際に90%でも残差はほぼゼロでアラートは鳴りません。逆に火曜午後の70%は、予測が40%だった分だけ残差が立つ。値の大小ではなく文脈からのずれを測る、という最初の目標がここで実現します。予測モデル自体の作り方は時系列予測を1から解説にあります。

ただし、大きな落とし穴があります。予測モデルが柔軟すぎると、異常まで再現してしまうのです。表現力の高いモデルを残差がゼロになるまで訓練すれば、スパイクごと予測してしまい、検知器は何も鳴らなくなる。異常検知の予測器は、わざと鈍く作るのが正しい。

FIG 1次数を上げるほど訓練データを忠実になぞる。異常検知ではこの「なぞりすぎ」が敵で、異常点まで予測されてしまえば残差はゼロになり、検知器は沈黙する

残差を手に入れたあと、いちばんやりがちな事故が「残差の絶対値が5を超えたら異常」と決め打ちすることです。残差のばらつきは時間帯で違います。深夜はトラフィックが小さいので残差も小さく、昼のピークでは同じ割合のずれでも絶対値が大きくなる。固定閾値は、昼に鳴りっぱなしで夜は何も拾わない検知器になります。

この先にあるもの

§

ここから先は会員限定です

解説記事371本・教科書26章・学生モード48単元・論文精読6本が、月額¥490ですべて読み放題になります。新しい解説は毎日3本ずつ増えます。いつでも解約でき、解約後も期間の終わりまで読めます。

会員の方はログインすると続きが表示されます

参考文献

  1. Bayesian Online Changepoint Detection. arXiv:0710.3742論文ページ·PDF
  2. Towards a Rigorous Evaluation of Time-series Anomaly Detection. arXiv:2109.05257論文ページ·PDF
  3. Current Time Series Anomaly Detection Benchmarks are Flawed and are Creating the Illusion of Progress. arXiv:2009.13807論文ページ·PDF

本記事は上記論文の本文にもとづいて執筆しています。数値・主張は原典を優先してください。

コメント

コメントにはログインが必要です