異常検知 — 正常を学び、外れを見つける

不正利用、機械の故障、サーバの障害。異常は数が少なく、事前にラベルもつけにくい。だから発想を変える — まず「正常とはどんな姿か」を学び、そこから外れたものを異常とする。統計・密度・時系列、3つのやり方を動かして、そして「しきい値を動かすと見逃しと誤検知が引っぱり合う」トレードオフを体感します。

1. 統計的異常検知 — 分布としきい値

もっとも素直な考え方。正常データが釣鐘型(正規分布)に散らばると仮定し、平均から ±kσ より外れた点を異常とみなします。「平均から何σ離れているか」を表す z スコア がそのまま異常度です。点が流れてくる様子と、しきい値を動かしたときの変化を見てください。

z スコア — 分布のすそから外れた点を捕まえる
青い曲線=正常データの分布、赤い点線=±kσ のしきい値。下に流れてくる点のうち、しきい値の外なら赤(異常判定)。○=本当の異常、●=正常データ。k を下げると誤検知が増え、上げると見逃しが増えます。
POINT — 「正常」を先に決める 異常検知は分類と違い、異常のサンプルをほとんど持たないまま始めることが多い。だから正常データだけから「ふつうの範囲」を学習し、そこに収まらないものを異常とする。z スコアはその最小の形 — 平均 μ と標準偏差 σ さえ分かれば異常度が測れる。
z = (x − μ) / σ , |z| > k ⇒ 異常 μ=平均、σ=標準偏差。k=3 なら正規分布の約99.7%が正常範囲に入る(3σ法)

2. しきい値のジレンマ — 見逃しと誤検知

しきい値は「甘く」も「厳しく」もできますが、ただ乗りはできません。正常と異常の分布は必ず少し重なっており、しきい値を下げれば異常を取りこぼさない代わりに正常を巻き込み(誤検知)、上げれば誤検知は減るが異常を見逃す。この綱引きが 適合率(Precision)と再現率(Recall) です。しきい値を左右に動かして、2つのメーターがシーソーする様子を見てください。

トレードオフ — 適合率と再現率のシーソー
青=正常の分布、赤=異常の分布。オレンジの線より右を「異常と判定」します。しきい値を左へ動かすと再現率↑(見逃し減)だが適合率↓(誤検知増)、右へ動かすとその逆。落ちてくる点がリアルタイムに仕分けされます。
注意 — 何を優先するかは用途しだい がん検診なら見逃しゼロを優先して再現率を上げる(誤検知は再検査で拾える)。逆にスパムフィルタは大事なメールを消さないため適合率を優先する。「精度99%」の一言は無意味 — 異常はもともと稀なので、全部「正常」と答えても精度は99%になってしまう。

3. 密度ベース — 孤立した点を見つける

分布を仮定できないときは、「まわりに仲間がいるか」で測ります。正常な点は密集し、異常な点はぽつんと孤立する。各点について k 番目に近い隣人までの距離(kNN距離)を異常度とし、これが大きい=孤立している点を異常とします。走査線が各点の近傍を調べていく様子を見てください。

密度ベース — kNN距離で孤立を測る
水色=正常、赤=異常。走査中の点から k 個の隣人へ線を引き、円の半径=k番目の隣人までの距離。この距離がしきい値より大きい(=スカスカな場所にいる)と異常。密集した点は円が小さく、孤立点は円が大きく赤くなります。
POINT — 距離が効くうちは、で注意 kNN・LOF(局所外れ値因子)・One-Class SVM・Isolation Forest など、密度や孤立度を使う手法は幅広い。ただし特徴量の次元が高すぎると「どの点も等しく遠い」次元の呪いで距離が意味を失う。埋め込みで次元を圧縮してから距離を測るのが実務の定石。

4. 時系列の異常 — 流れの中で見つける

センサやアクセスログのように止まらず流れ続けるデータでは、直近の正常な動きから「ふつうの帯」を学習し、そこを飛び出した瞬間に検出します。単発のスパイクも、水準がずれるレベルシフトも捕まえたい。感度(帯の幅)を変えて、検出のされ方がどう変わるか見てください。「異常を注入」ボタンでも試せます。

ストリーミング検知 — 学習した帯を飛び出したら発火
水色=流れる信号、青い帯=直近から学んだ正常範囲(移動平均 ±kσ)、赤い輪=帯を飛び出した異常。帯はゆっくり信号に追従するので、レベルシフトは飛び出した瞬間に検出され、やがて帯が追いつきます。感度を上げる(σを大きく)と見逃しやすく、下げると誤検知しやすい。

5. まとめ — 異常検知の三本柱

一歩先へ — 再構成で「正常」を学ぶ 深層学習の異常検知は「正常データだけで再構成を学ぶ」発想が主流。オートエンコーダは正常をうまく圧縮・復元できるが、異常はうまく復元できず再構成誤差が跳ね上がることで検出する。時系列なら予測モデルの残差、画像なら生成モデルの尤度。どれも本質は同じ — 正常の姿を深く学ぶほど、外れが際立つ。