運用・操作で動くシステムの異常検知:マルチモード/条件付き手法のサーベイ

工場のポンプを思い浮かべてください。朝、設備が待機モードから高負荷運転モードへ切り替わると、流量も振動も電流もいっせいに跳ね上がります。これは異常でしょうか? もちろん正常です——オペレーターがそう操作したのですから。では、待機モードのまま同じ大きさの跳ね上がりが起きたら? こちらは何かおかしい。

ここで効いているのは「いま、どんな運用状況か/どんな操作をしたか」という文脈です。「振動が大きい」という事実だけでは、正常か異常かを決められません。運用モード・制御入力・コマンド・setpoint といった「操作の情報」を知って初めて、その値が「操作で動いた当然の変動」なのか「説明のつかない逸脱」なのかを判断できます。

ところが、教科書的な異常検知——単一のガウス分布で正常範囲を決めたり、1個のオートエンコーダで再構成誤差を測ったり——は、この区別が苦手です。複数の運用モードをひとまとめに「正常」として学習すると、正常範囲がぶよぶよに膨らみ、モードの切り替えを異常と誤検知したり、逆にモードの隙間に紛れた本物の異常を見逃したりします。誤報が積み重なるとオペレーターはアラートを無視するようになり、本物の異常を見逃す——「オオカミ少年」問題です。

運用・操作で動いた分は異常としない、という異常検知の概念図

この記事は、「運用・操作によって動いた分を異常としない」異常検知を、トップ会議・主要ジャーナルの研究を踏まえてサーベイします。まず分野全体を俯瞰し、そのうえで主要な手法を一つずつ深掘りします。技術は大きく2系統に分かれます。

  • (あ) 条件付き異常検知 — 制御入力・コマンド・モードラベルを「条件」として明示的にモデルへ与え、「条件で説明できる変動」を差し引いて残りで異常を測る。
  • (い) マルチモード監視 — どのモードにいるかをデータから推定し、モードごとに別々の正常モデルを当てる。

これらを理解すると、次の場面で武器になります。

  • プラント・製造プロセス監視: バッチ/連続運転、グレード切替、起動・停止のたびに変わるセンサ系列から、本物の異常だけを切り出す
  • 設備・発電・空調(HVAC)監視: 負荷追従や季節モードで動く消費量・温度から、機器故障を切り分ける
  • 制御系・ICS監視: PLCのコマンドやアクチュエータ状態で動くセンサ値を、操作起因の変動と攻撃・故障の変動とに分離する
  • 回転機械・エンジンの健全性監視(PHM): 回転数・出力などの運転条件で大きく変わる振動・温度から、劣化だけを検出する

この記事の内容

  • なぜ「運用・操作で動いた分」を扱わないと破綻するのか(正常域が膨らむ問題)
  • 問題の定式化 — 「環境属性 / 指標属性」という考え方と、条件付き正常モデル $p(x\mid c)$
  • 分類体系 — (あ)条件付き と (い)マルチモード の2系統マップ
  • 各手法の深掘り — 条件付き異常検知の原型(Song+ 2007)、残差ベース、条件付き深層生成モデル、混合モデル+ベイズ融合(Yu&Qin 2008)、MoE/regime専門家、切替状態空間モデル
  • 評価とベンチマーク — TEP・C-MAPSS・SWaT と、遷移期・point-adjustの落とし穴
  • PyTorch実装 — 条件付きAEが「モードへの逸脱」を捉え、無条件モデルが取り違える様子を実測

前提知識

マハラノビス距離による異常検知
相関を考慮した距離。本記事のモード別監視の土台です。
混合ガウスモデルによる異常検知
多峰な正常分布の表現。マルチモード監視の出発点です。
オートエンコーダによる異常検知
再構成誤差で異常を測る考え方。条件付きAEの基礎です。

1. なぜ「操作で動いた分」を扱わないと破綻するのか

異常検知の素朴な戦略は「正常データの分布を覚え、そこから外れたら異常」というものです。ここで落とし穴になるのが、正常データが複数の運用モードを含むときです。

待機・高負荷・部分運転という3モードのセンサ点群を、ひとつのガウス分布で囲ってみましょう。左図がそれです。

無条件の単一ガウス監視とモード別監視の正常域の違い

左図(無条件)では、3つのモードを覆うように楕円が大きく広がります。すると2つの問題が同時に起きます。

  1. 見逃し: モードとモードの「谷間」(赤い星)は、どのモードの正常データからも遠いのに、全体の楕円の内側に入ってしまいます。本来あり得ない動作なのに「正常」と判定されます。
  2. 誤報: 各モードの端にある正常点は、全体平均から見ると遠いため「異常」と誤判定されがちです。

右図(モード別)では、モードごとに別々の楕円を当てます。谷間の異常はどのモードの楕円からも外れて正しく検出され、各モードの正常点はそれぞれの楕円の内側に収まります。

この直感が、本記事のすべての手法に共通する核心です。「全部まとめて正常」ではなく、「いまの運用・操作という条件のもとで正常か」を問う。次節でこれを定式化します。


2. 問題の定式化 — 環境属性と指標属性

「操作で動いた分を異常としない」を数式にするには、観測する量を2種類に分けるのが出発点です。これは条件付き異常検知の古典的論文 Song ら(IEEE TKDE, 2007)の用語が分かりやすいので、それを借ります。

  • 環境属性(environmental attributes) $c$ — 運用モード、制御入力 $u$、setpoint、コマンド、外生変数(気温・負荷指令など)。それ自体は異常判定に使わない量。「操作・状況」を表す。
  • 指標属性(indicator attributes) $x$ — センサ計測値。異常かどうかを判定したい量。

環境属性と指標属性、条件付きモデルの概念図

私たちが学習したいのは、無条件の分布 $p(x)$ ではなく、条件付き分布

$$ \begin{equation} p(x \mid c) \end{equation} $$

です。そして異常スコアは、その条件付き尤度の低さで測ります。

$$ \begin{equation} A(x, c) = -\log p(x \mid c) \end{equation} $$

直感は明快です。「いまモードB(高負荷運転)で、コマンドをこう打った」という条件 $c$ のもとで、観測 $x$ がありふれた値なら $p(x\mid c)$ は大きく、スコアは小さい(正常)。同じ $x$ でも「モードA(待機)」という条件のもとでは $p(x\mid c)$ が小さく、スコアは大きい(異常)。同じセンサ値でも、条件によって正常か異常かが変わる——これが無条件モデルには表現できなかった性質です。

無条件モデル $p(x)$ は、条件を周辺化した混合

$$ \begin{equation} p(x) = \sum_{c} p(x \mid c)\, p(c) \end{equation} $$

を見ているにすぎません。混合してしまうと、図2左のように正常域が膨らみ、条件ごとの差が消えます。情報(操作・モード)があるのに捨てているのが破綻の原因です。

ここから先は、この $p(x\mid c)$ を「どう与え、どう推定するか」で手法が分かれます。条件 $c$ が直接観測できるなら (あ) 条件付き、$c$ が隠れていてデータから推定するなら (い) マルチモード、という大きな分岐です。次節で全体地図を描きます。


3. 分類体系 — 2系統の全体地図

「運用・操作を踏まえた異常検知」を俯瞰すると、次のように整理できます。

運用・操作を踏まえた異常検知の分類体系マップ

系統 条件の与え方 代表アプローチ 正常モデル 向いている状況
(あ) 条件付き 制御入力・モードを明示的に入力 条件付き異常検知(Song+2007) / 残差ベース予測 / 条件付きVAE・正規化フロー / 文脈認識分解(Time-CAD) / 運転条件正規化(PHM) $p(x\mid c)$ を直接モデル化 操作・モードが観測できる(ログ・指令値がある)
(い) マルチモード モードをデータから推定 混合モデル+ベイズ融合(Yu&Qin2008) / 複数PCA / MoE・regime専門家(BAMoE) / 切替状態空間・HMM(DS3M) モードごとの局所モデルを切替 モードラベルがない/自動でモード分けしたい

この2系統は排他ではありません。実システムでは「モードラベルはあるが過渡(遷移)は推定したい」「制御入力+潜在モードの両方」のように混ぜて使います。以下、(あ)から順に深掘りします。


4. 【(あ)-1】条件付き異常検知の原型 — Song+ 2007

条件付き異常検知を最初に一般的な枠組みとして定式化したのが、Song, Wu, Jermaine, Ranka による “Conditional Anomaly Detection”(IEEE Transactions on Knowledge and Data Engineering, 2007)です。前節の「環境属性/指標属性」という用語はこの論文に由来します。

アイデアは、$p(x\mid c)$ を2つのガウス混合の対応づけとして表すことです。まず環境属性の分布を $K$ 個のガウス成分で表します。

$$ \begin{equation} p(c) = \sum_{i=1}^{K} \alpha_i\, \mathcal{N}(c \mid \mu_i^{U}, \Sigma_i^{U}) \end{equation} $$

同様に指標属性も $L$ 個のガウス成分 $\mathcal{N}(x\mid \mu_j^{V}, \Sigma_j^{V})$ で表します。そして「環境成分 $i$ にいるとき、指標成分 $j$ がどれくらい出やすいか」を表す対応行列 $p(V_j \mid U_i)$ を学習します。条件付き分布は

$$ \begin{equation} p(x \mid c) = \sum_{i=1}^{K} p(U_i \mid c) \sum_{j=1}^{L} p(V_j \mid U_i)\, \mathcal{N}(x \mid \mu_j^{V}, \Sigma_j^{V}) \end{equation} $$

となります。ここで $p(U_i\mid c)$ は「いまの環境(操作)$c$ がどの環境成分に属するか」、$p(V_j\mid U_i)$ は「その環境のもとでどのセンサ・パターンが正常か」を表します。これらのパラメータを EM アルゴリズムで推定します(論文では3種類のEM変種を提案)。

ポイントは、環境属性 $c$ の値そのものは異常スコアに入らないことです。$c$ がどんな極端な値でも、それが「どの指標パターンを引き起こすか」だけを通じて効きます。だから「珍しい操作をした」こと自体は異常になりません。異常になるのは「その操作のもとで、出てはいけないセンサ値が出た」ときだけ——まさに私たちが欲しい性質です。

この枠組みは古典ですが、考え方は現在の深層モデルにそのまま受け継がれています。違いは「ガウス混合の対応づけ」を「ニューラルネットの条件付け」に置き換えただけ、と言ってよいでしょう。次節では、もっと素直な「予測の残差」で同じことを実現する系統を見ます。


5. 【(あ)-2】残差ベース — 制御入力で予測し、残った分で検知

制御工学に馴染みのある人には、こちらの方が直感的かもしれません。制御入力 $u$ を使ってセンサ値を予測し、予測しきれなかった残差で異常を測るやり方です。

プラントの出力 $y_t$ が、過去の出力と制御入力で決まる動的システムだとします。線形なら ARX(外生入力付き自己回帰)モデル

$$ \begin{equation} \hat{y}_t = \sum_{k=1}^{n_a} a_k\, y_{t-k} + \sum_{k=1}^{n_b} b_k\, u_{t-k} \end{equation} $$

を正常データから同定し、残差

$$ \begin{equation} r_t = y_t – \hat{y}_t \end{equation} $$

を監視します。非線形なら $a_k, b_k$ をニューラルネット(NARX、RNN with exogenous input)に置き換えます。

制御入力で予測した残差では操作分が消え、異常だけ突出する図

上図がこの威力を示しています。上段:観測 $y$(青)は制御入力 $u$(灰破線)で操作されるたびに大きく動きます。生の $y$ だけを監視する素朴な検知器は、操作のたびに「大きく動いた!」と誤報を出します。下段:制御入力を知る予測器の残差 $r=y-\hat{y}(u)$ を見ると、操作で説明できる変動はきれいに消え、説明できない本物の異常(時刻14付近の突出)だけが残ります。

この「残差で異常を測る」考え方は、制御系・ICSのモデルベース監視と地続きです。プラントの物理モデルや、PLCロジックが課す不変則(invariant)——「ポンプがONなら下流タンクの水位は上がるはず」のような関係——を正常な振る舞いとし、それが破れたら異常とします。SWaT(Secure Water Treatment)のような水処理テストベッドでの異常検知研究は、まさにセンサとアクチュエータ(制御コマンド)の整合性を見ています。SWaTは51タグ(センサ25・アクチュエータ26)からなり、アクチュエータ状態=制御コマンドを条件として活用できる代表的ベンチマークです。

残差ベースの長所は、システム同定の理論がそのまま使え、解釈しやすいこと。短所は、良い予測モデル(物理 or 同定)が要ることと、フィードバック制御がかかっていると異常が制御で吸収されて残差に出にくくなる(closed-loop の難しさ)ことです。次節では、$p(x\mid c)$ をより柔軟にモデル化する深層生成モデルを見ます。


6. 【(あ)-3】条件付き深層生成モデル — cVAE・条件付き正規化フロー

ガウス混合や線形ARXでは表せない複雑な条件付き分布を扱うのが、深層生成モデルの条件付き版です。考え方は「VAE や正規化フローに、条件 $c$ を追加入力として注入する」だけ。

条件付きVAE/条件付き正規化フローの構造図

条件付きVAE(cVAE) では、エンコーダ $q(z\mid x, c)$ とデコーダ $p(x\mid z, c)$ の両方に条件 $c$(モードのone-hot、制御入力ベクトルなど)を結合して与えます。学習は通常のELBO

$$ \begin{equation} \mathcal{L} = \mathbb{E}_{q(z\mid x,c)}\big[\log p(x\mid z,c)\big] – \mathrm{KL}\big(q(z\mid x,c)\,\|\,p(z)\big) \end{equation} $$

を最大化します。条件 $c$ をデコーダに渡すので、デコーダは「このモードならこういう波形」を再現でき、再構成誤差(または再構成確率)が異常スコアになります。

条件付き正規化フロー は、可逆変換 $f_c$ で観測 $x$ を標準正規分布 $z$ に写し、変数変換公式で条件付き対数尤度を厳密に計算します。

$$ \begin{equation} \log p(x\mid c) = \log p_Z\!\big(f_c(x)\big) + \log\left|\det \frac{\partial f_c}{\partial x}\right| \end{equation} $$

異常スコアは $-\log p(x\mid c)$。正規化フローを多変量時系列の異常検知に条件付きで使う研究(例:条件付き正規化フローによる多変量時系列異常検知, ISA Transactions, 2023)では、過去の窓や外生変数を条件として与え、各時刻の条件付き尤度の低さで異常を判定します。VAEと違い尤度が近似でなく厳密に出るのが利点です。

この系統の身近な発展形が Time-CAD(文脈認識ディープ分解)です。曜日・祝日・時刻・運転モードといった文脈 $c$ で「説明できる変動」を分解の段階で取り除き、残差だけで異常を測ります。詳しくは個別記事に譲ります。

Time-CAD:コンテキストを考慮した時系列分解による異常検知
曜日・祝日・モードなどの文脈で説明できる変動を分解で除き、残差で検知。(あ)系統の深層版です。

なお PHM(健全性監視)の分野では、もっと素朴な「運転条件正規化」も実務で強力です。NASAのC-MAPSS(ターボファンエンジン)データセットのFD002・FD004は6つの運転条件を持ち、そのままでは劣化と運転条件変化が混ざります。そこで運転条件(高度・速度・出力)でデータをクラスタリングし、条件ごとに別々に正規化してから劣化を測る——これも立派な条件付き異常検知/予測です。次は条件が観測できない場合、すなわち(い)マルチモードに移ります。


7. 【(い)-1】マルチモード統計監視 — 混合モデル+ベイズ融合

ここからは「モードラベルが与えられない」場合です。データからモードを推定し、モードごとに局所モデルを当てます。プロセス監視(化学工学)で長く研究されてきた王道が、有限ガウス混合モデル(FGMM)+ベイズ推論です。代表が Yu & Qin による論文(AIChE Journal, 2008)です。

手順はこうです。まずラベルなしの正常運転データを $K$ 個のガウス成分(=運用モード)で表現します。

$$ \begin{equation} p(x) = \sum_{i=1}^{K} \pi_i\, \mathcal{N}(x \mid \mu_i, \Sigma_i) \end{equation} $$

成分数 $K$ は Figueiredo–Jain アルゴリズムなどで自動決定できます。各モード $i$ に対して局所的な監視統計($T^2$ 統計量や $Q$ 統計量、あるいはマハラノビス距離)を用意します。新データ $x_t$ が来たら、各モードへの所属確率 $P(\text{mode}_i\mid x_t)$ を事後確率として計算し、それを重みにして局所統計量を融合します。

FGMM+ベイズ推論によるマルチモード監視の概念図

具体的には、各モードの監視統計を確率(ベイズ推論ベースの指標 BIP)に変換し、所属確率で重み付けした統合指標

$$ \begin{equation} \mathrm{BIP}(x_t) = \sum_{i=1}^{K} P(\text{mode}_i \mid x_t)\, P_i(x_t) \end{equation} $$

を監視します。$P_i(x_t)$ はモード $i$ の局所統計が閾値を超える確率です。こうすると、いまどのモードにいるかを陽に判定しなくても、自動的に「もっとも近いモードの基準」で評価されます。モード境界付近では複数モードの基準がなめらかに混ざるので、急なモード切替でも破綻しにくいのが利点です。

この系統には、変分ベイズGMM+正準相関分析(CCA)でモード識別と局所故障検知を組み合わせる発展(IEEE系, 2019)や、複数のPCAモデルをモードごとに持つ「マルチモデルPCA」など多くの派生があります。共通する弱点は遷移(過渡)モードで、起動・停止・グレード切替の最中はどの定常モードにも当てはまらず、誤報の温床になります(後述)。次は、同じ「専門家を切り替える」発想を深層学習で行うMoEです。


8. 【(い)-2】MoE・切替状態空間 — 専門家を切り替える深層手法

混合モデル+ベイズ融合の深層版が、Mixture of Experts(MoE) です。モードごとに「専門家」ネットワークを用意し、ゲーティング(門番)ネットワークが入力に応じて専門家を選びます。

$$ \begin{equation} \hat{x} = \sum_{i=1}^{E} g_i(x)\, \text{Expert}_i(x), \qquad \sum_i g_i(x) = 1 \end{equation} $$

ゲート $g_i$ が「いまどのモード(regime)か」を softmax で柔らかく判定し、その専門家が正常パターンを再構成・予測します。異常は再構成誤差で測ります。この発想は、多変量時系列に双方向(時間×チャネル)注意とMoEを組み合わせる BAMoE や、指標間の目標衝突を専門家分担で解く Conflict-Aware AD などに結実しています。

Bi-Attention × Mixture-of-Experts による異常検知
複数regimeを専門家に分担させるMoEの深掘り。(い)系統の深層実装です。
Conflict-Aware Anomaly Detection(CAD)
指標間の勾配衝突をMoE模倣で解く。マルチモード×多変量の難所に効きます。

モードを潜在状態として時間方向に推定するなら、切替状態空間モデル(switching state-space model)/隠れマルコフモデル(HMM) が自然です。

切替状態空間モデル/HMMによるモード推定の概念図

潜在モード $z_t$ がマルコフ連鎖

$$ \begin{equation} P(z_t = j \mid z_{t-1} = i) = A_{ij} \end{equation} $$

に従って遷移し、モードごとに異なる観測力学(線形なら状態空間、非線形ならMLP/RNN)が当てられます。推論は switching Kalman filter や前向き・後ろ向きアルゴリズムで行い、各時刻のモード事後確率と予測残差から異常を測ります。深層版では、RNNと非線形切替状態空間を融合した DS$^3$M(Deep Switching State Space Model, 2021)のように、非線形な力学と不規則なモード切替を同時に捉える研究があります。状態空間ベースの異常検知では「残差が非定常になりベースラインのずれを異常と誤認する」「検出後に新しいモードへ適応するのに時間がかかる」という固有の難しさも指摘されています。

画像なし
隠れマルコフモデルと前向き・後ろ向きアルゴリズム
潜在モードの推定の土台。切替状態空間モデルの基礎です。

MoEが「空間的にモードを分担」するのに対し、切替状態空間は「時間的にモードの遷移を追う」——同じマルチモードでも軸が違うことを押さえておくと選びやすくなります。次は、すべての手法に共通してつきまとう評価の落とし穴です。


9. 評価とベンチマーク — 遷移期とpoint-adjustの落とし穴

運用・操作を踏まえた異常検知を評価するとき、定番ベンチマークと固有の注意点があります。

ベンチマーク 分野 モード・操作の性質
TEP(Tennessee Eastman Process) 化学プロセス 6つの生産モード+モード遷移を含む拡張版あり。マルチモード監視の定番
C-MAPSS FD002 / FD004 航空エンジンPHM 6運転条件で劣化と条件変化が混ざる。運転条件正規化の検証に
SWaT / WADI 水処理ICS センサ+アクチュエータ(制御コマンド)。残差・不変則ベースの検証に
SMD / MSL / SMAP / PSM サーバ・設備・インフラ 多変量時系列。モード切替を含む実運用データ

最大の難所は モード遷移(過渡) です。

モード遷移(過渡)を異常と取り違える問題の図解

起動・停止・グレード切替の最中は、どの定常モードの正常モデルにも当てはまりません。素朴な手法は、この「操作による正常な過渡」を変化点=異常と取り違えて誤報を量産します(図の赤い帯)。対策は、(1)遷移を独立の「遷移モード」として別モデルで扱う、(2)ベイズ融合で複数モードの基準をなめらかに混ぜる、(3)制御入力を条件に入れて過渡そのものを予測する、のいずれかです。

もう一つの落とし穴は評価指標です。時系列異常検知で広く使われてきた point-adjust F1 は、一区間の一点でも当てればその区間を全部正解にしてしまうため、ランダムな検知器でも高いスコアが出る水増しが知られています。マルチモードの設定では「モード境界で偶然アラートが出た」だけで高F1になりかねません。閾値非依存の AUC や VUS、区間ベースの指標を併用すべきです。

VUS:時系列異常検知の頑健な評価指標
point-adjust水増しを避ける閾値非依存・パラメータフリー指標。
時系列異常検知サーベイ(評価の落とし穴つき)
評価指標とベンチマーク刷新の全体像。本記事の評価編の親記事です。

では、実際に「条件を入れる」とどれだけ効くのか。最後にPyTorchで測ります。


10. PyTorch実装 — 条件付きAEは「モードへの逸脱」を捉える

「操作・モードを条件に入れると、無条件モデルが取り違える異常を捉えられる」ことを、合成データで実測します。

設定:6センサ・3モードの正常データを作ります。モードごとに平均と相関(共分散)が違います。異常は「本来のモードからは外れるが、別モードの方向へ部分的にずれた」点——つまり全体で見ると正常データに紛れる、いやらしい異常です。

import numpy as np, torch, torch.nn as nn
torch.manual_seed(0); np.random.seed(0); rng = np.random.default_rng(0)

D, M, N_per = 6, 3, 1500          # センサ数, モード数, モードごとサンプル数
means = rng.normal(0, 2.5, (M, D))
covs = [ (lambda A: A@A.T/D + 0.15*np.eye(D))(rng.normal(0,1,(D,D))) for _ in range(M) ]

X, C = [], []
for m in range(M):
    X.append(rng.multivariate_normal(means[m], covs[m], N_per)); C.append(np.full(N_per, m))
X = np.vstack(X); C = np.concatenate(C)
perm = rng.permutation(len(X)); X, C = X[perm], C[perm]

mu_all, sd_all = X.mean(0), X.std(0)              # 全体で標準化
Xs = (X - mu_all) / sd_all
n_tr = int(0.7*len(Xs))
Xtr, Ctr = Xs[:n_tr], C[:n_tr]
Xte_n, Cte_n = Xs[n_tr:], C[n_tr:]

異常データは「本来のモード $m$ のラベルを持つが、値は別モードの方向へ0.55だけずれた」点として作ります。ラベル(条件)は本来のモード $m$ のままなので、条件を知るモデルだけが「このモードにしては変だ」と気づけます。

Xan, Can = [], []
for _ in range(len(Xte_n)):
    m = rng.integers(M)
    wrong = (m + rng.integers(1, M)) % M          # 別モードの方向
    tgt = means[m] + 0.55*(means[wrong] - means[m])
    x = rng.multivariate_normal(tgt, covs[m], 1)[0]
    Xan.append((x - mu_all)/sd_all); Can.append(m)  # ラベルは本来のモードm
Xan = np.vstack(Xan); Can = np.array(Can)

Xte = np.vstack([Xte_n, Xan]); Cte = np.concatenate([Cte_n, Can])
yte = np.concatenate([np.zeros(len(Xte_n)), np.ones(len(Xan))])
onehot = lambda c: np.eye(M)[c]

素のAE(条件なし)と条件付きAE(モードのone-hotを入力)を用意します。ボトルネックは狭め(潜在2次元)にして、容量で力押しできないようにします。

class AE(nn.Module):
    def __init__(s, din, h=16, z=2):
        super().__init__()
        s.enc = nn.Sequential(nn.Linear(din,h), nn.ReLU(), nn.Linear(h,z))
        s.dec = nn.Sequential(nn.Linear(z,h),   nn.ReLU(), nn.Linear(h,din))
    def forward(s,x): return s.dec(s.enc(x))

class CAE(nn.Module):                              # 条件付き: 入力にモードone-hotを結合
    def __init__(s, din, M, h=16, z=2):
        super().__init__()
        s.enc = nn.Sequential(nn.Linear(din+M,h), nn.ReLU(), nn.Linear(h,z))
        s.dec = nn.Sequential(nn.Linear(z+M,h),   nn.ReLU(), nn.Linear(h,din))
    def forward(s,x,c):
        z = s.enc(torch.cat([x,c],1))
        return s.dec(torch.cat([z,c],1))

学習して、テストデータの再構成誤差を異常スコアにします。比較対象として、モードを知っている「モード別マハラノビス」と、知らない「無条件マハラノビス」も計算します。

Xtr_t = torch.tensor(Xtr, dtype=torch.float32)
Ctr_t = torch.tensor(onehot(Ctr), dtype=torch.float32)
Xte_t = torch.tensor(Xte, dtype=torch.float32)
Cte_t = torch.tensor(onehot(Cte), dtype=torch.float32)

def train(model, cond):
    opt = torch.optim.Adam(model.parameters(), lr=5e-3)
    for _ in range(400):
        opt.zero_grad()
        out = model(Xtr_t, Ctr_t) if cond else model(Xtr_t)
        loss = ((out - Xtr_t)**2).mean(); loss.backward(); opt.step()

ae  = AE(D);    train(ae,  False)
cae = CAE(D,M); train(cae, True)
with torch.no_grad():
    e_ae  = ((ae(Xte_t)         - Xte_t)**2).mean(1).numpy()
    e_cae = ((cae(Xte_t, Cte_t) - Xte_t)**2).mean(1).numpy()

# モード別 / 無条件マハラノビス
inv = [np.linalg.inv(np.cov(Xtr[Ctr==m].T)+1e-3*np.eye(D)) for m in range(M)]
mus = [Xtr[Ctr==m].mean(0) for m in range(M)]
d_mode = np.array([(Xte[i]-mus[Cte[i]])@inv[Cte[i]]@(Xte[i]-mus[Cte[i]]) for i in range(len(Xte))])
inv0 = np.linalg.inv(np.cov(Xtr.T)+1e-3*np.eye(D)); mu0 = Xtr.mean(0)
d_glob = np.array([(Xte[i]-mu0)@inv0@(Xte[i]-mu0) for i in range(len(Xte))])

def auc(s, y):
    order = np.argsort(s); ranks = np.empty(len(s)); ranks[order] = np.arange(1,len(s)+1)
    npos = y.sum(); nneg = len(y)-npos
    return (ranks[y==1].sum() - npos*(npos+1)/2) / (npos*nneg)

for name, s in [("無条件マハラノビス",d_glob),("素のAE",e_ae),("条件付きAE",e_cae),("モード別マハラノビス",d_mode)]:
    print(f"{name}: AUC={auc(s,yte):.3f}")

実行結果は次の通りです(seed固定)。

無条件マハラノビス: AUC=0.367
素のAE:           AUC=0.860
条件付きAE:        AUC=0.962
モード別マハラノビス: AUC=0.990

条件付きAEと各手法のAUC比較、誤差分布の図

結果の読み取りは劇的です。

  • 無条件マハラノビス=0.367:ランダム(0.5)を下回っています。モードを無視すると、「別モードへ紛れた異常」は全体平均から見るとむしろ近く見えるため、正常点より正常らしく評価してしまう——図2左で見た「正常域が膨らむ」破綻がそのまま数字に出ました。
  • 素のAE=0.860:条件なしでも非線形なので無条件マハラノビスよりはマシですが、3モードを狭い潜在に押し込むため正常の再構成自体が甘く、異常との差がつきにくい。
  • 条件付きAE=0.962:モードを条件に入れた瞬間、デコーダが「このモードならこの値」を再現できるようになり、モードへの逸脱がくっきり誤差に出ます。右図の通り、正常(水色)と異常(赤)の再構成誤差分布がきれいに分離します。
  • モード別マハラノビス=0.990:モードを知っていれば、線形のマハラノビスでもほぼ完璧。「条件を入れること」自体が効いていることの証拠です。

この実験の教訓は明快です。手法の新しさよりも、「運用・操作という条件を正常モデルに入れたか」が決定的だということ。条件を入れさえすれば、古典的なマハラノビスでも最新のAEでも、モードに紛れた異常を捉えられます。逆に、どんなに高度なモデルでも条件を捨てれば破綻します。


11. まとめ — どの手法を選ぶか

「運用・操作で動くシステムの異常検知」を、2系統に整理して俯瞰しました。選び方の指針をまとめます。

状況 推奨アプローチ
制御入力・コマンドがログとして取れる (あ) 残差ベース(ARX/NARX/RNN)または条件付き生成モデル。操作で説明できる分を予測で消す
モードラベルは取れるが過渡が問題 条件付きモデル+遷移モードの別扱い。制御入力で過渡を予測
モードラベルがない/自動で分けたい (い) FGMM+ベイズ融合MoE。データからモードを推定
モードが時間的に切り替わる(系列が主役) 切替状態空間モデル/HMM。潜在モードを時間方向に追跡
多変量で指標間の目標が衝突 MoE系(BAMoE / Conflict-Aware)で専門家分担

共通する原則は、本記事の実験が示した通りです——「操作で動いた分」を正常モデルに条件として与え、説明できない残りだけで異常を測る。これさえ外さなければ、手法の選択は「条件が観測できるか」「モードが既知か」「遷移が頻繁か」という実務的な問いに落とし込めます。

各手法のさらなる深掘りは、以下の個別記事へどうぞ。

Time-CAD:コンテキストを考慮した時系列分解による異常検知
(あ)条件付きの深層版。文脈で説明できる変動を分解で除く。
Bi-Attention × Mixture-of-Experts による異常検知
(い)マルチモードのMoE実装。専門家でregimeを分担。
Conflict-Aware Anomaly Detection(CAD)
多変量×マルチモードの目標衝突を解く。
時系列異常検知サーベイ
分野全体のパラダイムと評価の落とし穴。

主な参考文献

  • X. Song, M. Wu, C. Jermaine, S. Ranka, “Conditional Anomaly Detection,” IEEE Transactions on Knowledge and Data Engineering, 19(5), 631–645, 2007.
  • J. Yu, S. J. Qin, “Multimode process monitoring with Bayesian inference-based finite Gaussian mixture models,” AIChE Journal, 54(7), 1811–1829, 2008.
  • 条件付き正規化フローによる多変量時系列異常検知, ISA Transactions, 2023.
  • Deep Switching State Space Model (DS$^3$M) for Nonlinear Time Series Forecasting with Regime Switching, arXiv:2106.02329, 2021.
  • C-MAPSS(NASA ターボファンエンジン劣化シミュレーション, FD001–FD004)/ Tennessee Eastman Process(拡張マルチモード版)/ SWaT・WADI(水処理ICSテストベッド).