前回までは、センサ値という連続量を予測して残差で異常を測る話でした。

しかし産業制御システム(CPS / ICS)の「操作」の多くは、離散的なコマンドです。「ポンプをON」「バルブを開」——PLC(プログラマブル・ロジック・コントローラ)がこうした指令を出し、アクチュエータが状態を変えます。ここで監視すべきは連続値の残差ではなく、アクチュエータが正しい状態にいるか、状態の移り変わりが正常かです。
この記事が掘り下げるのは、サイバーフィジカルシステムの異常検知をアクチュエータ状態遷移モデルで行う手法です(Pandey & Das, “Anomaly detection in cyber-physical systems using actuator state transition model,” International Journal of Information Technology, 2025 を念頭に置きます)。アイデアは、アクチュエータを有限状態機械(FSM)としてモデル化し、「コマンド → 状態 → センサ」の3者のつじつまが合っているかを監視する、というものです。

なぜこれが重要かというと、攻撃者はセンサ値を正常に見せかけたまま、アクチュエータの状態報告だけを偽装できるからです(False Data Injection)。連続値の閾値監視はこうしたステルス攻撃をすり抜けますが、状態の整合性チェックは見逃しません。本記事では、それを実データで証明します。
この手法が効く場面は明確です。
- 水処理・上下水道のICS: SWaT のようにポンプ・バルブが主役で、攻撃がアクチュエータ状態を狙う
- 製造ライン・バッチプロセス: 工程ステップ(状態)が決まった順序で進む系
- 電力・配電の保護リレー: 開閉状態の遷移が安全制約を持つ系
この記事の内容
- アクチュエータを有限状態機械(FSM)でモデル化する
- 遷移の正当性 — マルコフ遷移確率と「遷移の意外さ」スコア
- コマンドと実状態の照合(command-state consistency)
- センサ-アクチュエータ整合性 — 状態と物理応答の矛盾を突く
- 原論文(Pandey & Das, 2025)のアーキ — DNN分類器でセンサから「あるべき状態」を予測し、ハミング距離でずれを測る(SWaTでF1=0.96)
- 滞留時間(dwell time)の異常 — 遷移にかかる時間の監視
- NumPy実装 — 状態チャネル攻撃3種を生成し、生センサがほぼ無力な一方、状態遷移+整合性が捉える様子を実測
前提知識

1. アクチュエータを有限状態機械でモデル化する
電動バルブを考えます。バルブは連続値ではなく、いくつかの離散状態を取ります:「閉」「開動作中」「開」「閉動作中」。状態が変わるのは、コマンド(開指令・閉指令)や物理的完了(動作が終わる)といったイベントが起きたときです。
この構造はそのまま有限状態機械(FSM, Finite State Machine)で表せます。FSMは、状態・状態遷移・遷移を許す条件(トリガ)からなる古典的なモデルです。

正常なバルブは「閉 →(開指令)→ 開動作中 →(完了)→ 開 →(閉指令)→ 閉動作中 →(完了)→ 閉」という決まった経路をたどります。ここで重要なのは、「閉」から直接「開」へ瞬間移動することは物理的にあり得ない(図の赤い矢印)こと。開くには必ず「開動作中」を経るので、時間がかかります。この「あり得ない遷移」を検出するのが、状態遷移モデルの第一の役割です。
複数のアクチュエータをまとめて1つのマクロ状態として扱うこともできます。たとえばポンプ $P\in\{0,1\}$ とバルブ $V\in\{0,1\}$ をまとめて $s = 2P + V \in \{0,1,2,3\}$ とすれば、システム全体の運転状態を1つの離散変数で表せます。次節では、この状態系列の「正常さ」を確率でモデル化します。
2. 遷移の正当性 — マルコフ遷移確率
正常運転データから、状態 $s$ がどう移り変わるかの統計を学びます。もっとも素直なのは1次マルコフ連鎖で、遷移確率行列
$$ \begin{equation} M_{ij} = P(s_t = j \mid s_{t-1} = i) \end{equation} $$
を正常データの遷移回数から推定します(各行が確率1に正規化)。

行列を見ると、正常運転で頻繁に起きる遷移(対角=状態維持や、隣接状態への移動)は高い確率を持ち、正常では決して起きない遷移は確率がほぼ0です。そこで異常スコアを「遷移の意外さ(surprise)」、すなわち遷移の負の対数尤度で定義します。
$$ \begin{equation} A_t = -\log P(s_t \mid s_{t-1}) = -\log M_{s_{t-1}, s_t} \end{equation} $$
正常な遷移なら $M$ が大きいのでスコアは小さく、正常データに無い遷移(たとえば $P0V0 \to P1V1$ のような同時2ビット変化)を踏むと $M\approx 0$ なのでスコアが跳ね上がります。これは前提記事の隠れマルコフモデルと同じ「状態遷移の尤度」の考え方です。
遷移確率は「状態系列の文法」を学んでいるとも言えます。しかし、状態の報告値そのものが偽装されている場合はどうでしょうか。報告される遷移が文法的に正しく見えても、物理と矛盾していることがあります。そこで次の柱が要ります。
3. コマンドと実状態、そしてセンサとの整合性
3.1 コマンドと実状態の照合
もっとも基本的なチェックは、PLCが出したコマンドと、アクチュエータが報告する実状態が一致しているかです。

「ポンプON指令を出したのに状態がOFFのまま」なら、アクチュエータが応答していない(故障 or 妨害)。「バルブ開指令を出したのに閉のまま」なら固着が疑われます。コマンドと状態のペアを照合するだけで、実行されなかった操作を捉えられます。
3.2 センサ-アクチュエータ整合性
さらに強力なのが、アクチュエータ状態とセンサの物理応答の整合性です。アクチュエータが本当にその状態なら、センサは対応する物理変化を示すはずです。

バルブが「開」を報告しているのに流量がゼロなら、それは物理的に矛盾しています——固着か、状態報告のなりすましです。これを定量化するには、各状態 $s$ における期待される物理変化(たとえば水位の変化 $\Delta L$)を正常データから学び、報告状態の期待値と実測のずれを残差にします。
$$ \begin{equation} C_t = \left| \Delta y_t – \mathbb{E}[\Delta y \mid s = s_t^{\text{報告}}] \right| \end{equation} $$
報告状態が物理と合っていればこの残差は小さく、なりすまし(報告は「ポンプON」だが実際は水位が増えない)では大きく跳ねます。これが、センサ値を正常に見せかけたステルス攻撃を暴く鍵です。
整合性チェックは、機械学習でも実装できます。

センサ文脈(水位・流量・圧力)から「本来あるべきアクチュエータ状態」を予測する分類器 $\hat{s} = f(y)$ を学習し、報告状態 $s$ と予測状態 $\hat{s}$ が食い違えば異常とします。実際、AIベースの分類器でアクチュエータ状態を予測し、実状態と突き合わせる手法が報告されています。この「予測状態 vs 実状態」の照合を、複数アクチュエータへ一気に拡張して定量化したのが、本記事が念頭に置く原論文です。次節でそのアーキを具体化します。
4. 原論文のアーキを読み解く — DNN分類器とハミング距離
ここまでの「状態遷移」「整合性」「予測器」という柱を、実際に1つの異常検知器へ統合した代表研究が Pandey & Das (2025) です。本節では、この論文の手法をアーキ・スコア・新規性・データフローのレベルで具体化します。
書誌: R. K. Pandey, T. K. Das, “Anomaly detection in cyber-physical systems using actuator state transition model,” International Journal of Information Technology, vol. 17, pp. 1509–1521, 2025. DOI: 10.1007/s41870-024-02128-x.
なお原論文の本文・図は出版社(Springer)の有料公開であり、図を直接引用できません。そこで以下の図は、論文が記述する手法を一般化・匿名化して再現した自作図です(実機テストベッドの固有構成は描かず、一般語のポンプ・バルブで表します)。
4.1 全体アーキ — 訓練と検知の2フェーズ
この手法の核心は、「センサ観測から、本来あるべきアクチュエータ状態を予測する分類器」を学習し、報告された実状態とのずれを測ることです。物理方程式を人手で書き下す(physics-based specification)必要はなく、正常運転データだけからデータ駆動で各制御系の挙動を学びます。これが第一の新規性です。

出典: Pandey & Das, Int. J. Inf. Technol., 2025(論文記述に基づく自作再現図)
上段が訓練フェーズです。正常時のセンサ観測ベクトル $\mathbf{y}$ を入力に、深層ニューラルネットワーク(DNN)分類器 $f_\theta$ が各アクチュエータの状態を予測します。教師信号は、その瞬間に実際に観測されたアクチュエータ状態ベクトル $\mathbf{a}$ です。つまり「センサがこうなっているとき、アクチュエータはこの状態であるはず」というセンサ→状態の写像を、正常データから教師あり学習で覚え込ませます。
下段が検知フェーズです。運用中のセンサ観測 $\mathbf{y}_t$ を学習済みの $f_\theta$ に通し、「あるべき状態」 $\hat{\mathbf{a}}_t = f_\theta(\mathbf{y}_t)$ を予測します。これを、システムが報告している実状態 $\mathbf{a}_t$ と照合します。正常なら両者はほぼ一致するはずで、攻撃や故障で状態が偽装・逸脱すると食い違いが生じます。
ポイントは、第2節のマルコフ遷移モデルが状態系列そのものの文法($s_{t-1}\to s_t$ の尤度)を見ていたのに対し、この手法はセンサ文脈と状態の整合($\mathbf{y}\to\mathbf{a}$ の写像)を見ている点です。両者は相補的で、論文は後者を主軸に据えます。では、その「食い違い」をどう1つの数値にするのでしょうか。
4.2 異常スコア — ハミング距離
複数のアクチュエータ状態は、ON/OFF や開/閉といった離散ビットのベクトル $\mathbf{a} = (a_1, a_2, \dots, a_m)$ で表せます($m$ はアクチュエータ数、SWaT では約26)。予測状態 $\hat{\mathbf{a}}$ と実状態 $\mathbf{a}$ のずれを測るのに最も自然なのが、一致しないビットの数=ハミング距離です。
$$ \begin{equation} d_H(\mathbf{a}_t, \hat{\mathbf{a}}_t) = \sum_{j=1}^{m} \mathbb{1}\!\left[a_{t,j} \neq \hat{a}_{t,j}\right] \end{equation} $$
ここで $\mathbb{1}[\cdot]$ は指示関数(条件が真なら1、偽なら0)です。$d_H$ は「いくつのアクチュエータについて、報告状態と『あるべき状態』が食い違ったか」をそのまま数えた整数です。論文が「予測状態と実状態の間のハミング距離こそが鍵」と述べるのは、この量がCPS全体の状態の不整合度を端的に表すからです。

出典: Pandey & Das, Int. J. Inf. Technol., 2025(論文記述に基づく自作再現図)
左図は照合のイメージです。予測ベクトル $\hat{\mathbf{a}}$(緑)と実ベクトル $\mathbf{a}$(青)をビットごとに比べ、食い違ったビット(赤枠)を数えると $d_H=2$ になります。右図は、正常時と異常時で $d_H$ の分布がどう分かれるかを示したものです。正常時は分類器の予測がよく当たるので $d_H$ は0近傍に集中し、攻撃時は不一致が増えて分布が右へ広がります。そこで閾値 $\tau$ を超えたら異常と判定します。
$$ \begin{equation} \text{異常} \iff d_H(\mathbf{a}_t, \hat{\mathbf{a}}_t) > \tau \end{equation} $$
連続値の残差(前記事)が実数の大小だったのに対し、ここでは離散ビットの不一致数という非常に解釈しやすい量で異常度が出るのが特徴です。「いま3つのアクチュエータが、センサと整合しない状態を報告している」と、運用者にそのまま提示できます。
4.3 なぜこの照合がステルス攻撃に強いのか
第3節で触れた「センサを正常に見せたまま状態だけ偽装する」ステルス攻撃に、この枠組みがなぜ効くのかを整理します。

出典: Pandey & Das, Int. J. Inf. Technol., 2025(論文記述に基づく自作再現図)
鍵は、学習済みの $f_\theta$ がセンサと状態の物理的な結びつきを内部に保持していることです。攻撃者がアクチュエータ状態 $\mathbf{a}$ だけを偽装しても、センサ $\mathbf{y}$ から計算される「あるべき状態」 $f_\theta(\mathbf{y})$ は本物の物理を反映したままなので、両者がずれてハミング距離が立ち上がります。逆にハミング距離を立てないためには、攻撃者はセンサと状態を同時に、互いに整合するように偽装しなければならず、これは単独チャネルの改ざんよりはるかに困難です。これが、複数センサ・複数アクチュエータをまたいだ整合性チェックの強みです。
4.4 評価データセットと性能
論文は、ICS異常検知の標準ベンチマークである SWaT(Secure Water Treatment、iTrust/SUTD)で評価しています。

出典: SWaT 仕様(iTrust/SUTD)に基づく匿名化自作図
SWaT は実際の上水処理を縮約した6段プロセスのテストベッドで、各段に取水・前処理・膜ろ過・脱塩素・逆浸透・貯留の工程が並び、段ごとにポンプ・バルブが配置されます。記録される属性は計51で、連続センサ約25(流量・水位・圧力・水質)と整数アクチュエータ状態約26からなり、サンプリング間隔は1秒です。正常運転7日分に加え、攻撃を仕掛けた4日分(約36件の攻撃シナリオ、攻撃点は全体の約12%)が含まれます。本手法はこの「アクチュエータ状態が約26ビットのベクトルになる」構造をそのまま $\mathbf{a}$ として活用します。

出典: 本手法のF1は Pandey & Das, 2025 の報告値。他手法は各公表水準に基づく概略
論文が報告する検知性能は F1スコア 0.96 で、再構成ベース(オートエンコーダ)や予測ベース(LSTM)、時間オートマトン(TABOR)、確率的RNN(OmniAnomaly)といった代表的手法を上回る水準です。F1が高いのは、precision(誤検知の少なさ)とrecall(取りこぼしの少なさ)の両立を意味します。状態の整合性という物理に根ざした手がかりを使うことで、正常な操作起因の変動を誤って異常としにくく、かつ巧妙な状態偽装も取りこぼしにくい——これがハミング距離ベースの照合の効きどころです。
ここまでが原論文のアーキの骨子です。手法を式とデータフローで押さえたところで、次は実際にアクチュエータを狙う攻撃の類型と、状態そのものに加えて時間の異常をどう捉えるかを見ます。
5. 攻撃の類型と滞留時間の異常
アクチュエータを狙う異常・攻撃には、いくつかの典型パターンがあります。

- コマンド実行不一致: ON指令でもOFFのまま動かない(故障・妨害)
- なりすまし(spoofing): 実際はOFFなのにONと報告(False Data Injection)
- 不正な遷移: 正常では現れない状態ジャンプ
- タイミング異常: 遷移の途中で固着・遅延
最後のタイミング異常は、状態そのものではなく状態に留まる時間(dwell time)の監視で捉えます。

正常なら「開動作中」は数ステップで「開」に遷移するはずです。ところが遷移状態に異常に長く留まれば、固着や機構の劣化が疑われます。各状態の滞留時間にも正常範囲を学習し、それを超えたら異常とします。これは時間トリガ型ハイブリッドオートマトンとして定式化できます。
理屈が揃ったので、実データで効果を確かめます。
6. NumPy実装 — ステルスな状態なりすましを暴く
水タンク制御を離散シミュレーションします。ポンプ $P$ が流入、バルブ $V$ が流出を担い、PLCがヒステリシス制御で水位 $L$ を一定範囲に保ちます。
import numpy as np
rng = np.random.default_rng(0)
N = 6000
lo, hi = 0.3, 0.7
L = np.zeros(N); P = np.zeros(N, int); V = np.zeros(N, int); L[0] = 0.5
Vsched = np.zeros(N, int); t = 0
while t < N: # バルブは需要に応じてランダム開閉
dur = rng.integers(150, 400); Vsched[t:t+dur] = rng.integers(0, 2); t += dur
for k in range(1, N):
if L[k-1] < lo: P[k] = 1 # PLCヒステリシス制御
elif L[k-1] > hi: P[k] = 0
else: P[k] = P[k-1]
V[k] = Vsched[k]
L[k] = np.clip(L[k-1] + 0.02*P[k] - 0.018*V[k] + rng.normal(0, 0.003), 0, 1)
マクロ状態 $s = 2P + V$ を作り、正常前半から遷移確率行列 $M$ と状態別の期待水位変化 $\mathbb{E}[\Delta L \mid s]$ を学習します。
s = 2*P + V
dL = np.diff(L, prepend=L[0])
exp_dL = {st: dL[s == st].mean() for st in range(4)} # 状態別の期待ΔL
tr_end = 3500
M = np.ones((4, 4)) * 1e-6
for k in range(1, tr_end):
M[s[k-1], s[k]] += 1
M /= M.sum(1, keepdims=True) # 遷移確率行列
ここがポイント。攻撃は報告される状態 s_obs だけを改ざんし、水位センサは真の状態で動いたまま(正常)にします。これが現実的なステルス攻撃(アクチュエータ feedback の偽装)で、連続値の閾値監視では見えません。
s_obs = s.copy(); label = np.zeros(N, int)
a1 = np.arange(4000, 4120); s_obs[a1] = s[a1] ^ 2; label[a1] = 1 # ポンプ状態なりすまし
a2 = np.arange(4600, 4680); s_obs[a2] = np.where(a2 % 2 == 0, 0, 3); label[a2] = 1 # 不正遷移
a3 = np.arange(5000, 5120); s_obs[a3] = s[a3] ^ 1; label[a3] = 1 # バルブ状態なりすまし
dL_obs = dL.copy() # センサは正常
3つの検知器を比べます。(1) 遷移の意外さ、(2) センサ整合性、(3) その統合、そしてベースラインの (4) 生水位の偏差。
trans = np.concatenate([[0], [-np.log(M[s_obs[k-1], s_obs[k]] + 1e-9) for k in range(1, N)]])
cons = np.array([abs(dL_obs[k] - exp_dL[s_obs[k]]) for k in range(N)])
tn = (trans - trans[:tr_end].mean()) / (trans[:tr_end].std() + 1e-9)
cn = (cons - cons[:tr_end].mean()) / (cons[:tr_end].std() + 1e-9)
comb = np.maximum(tn, cn) # 統合スコア
raw = np.abs(L - np.median(L)) # 生センサ(正常なので無力なはず)
def auc(score, y):
order = np.argsort(score); ranks = np.empty(len(score)); ranks[order] = np.arange(1, len(score)+1)
npos = y.sum(); nneg = len(y) - npos
return (ranks[y==1].sum() - npos*(npos+1)/2) / (npos*nneg)
for name, sc in [("生水位の偏差", raw), ("遷移の意外さ", trans), ("センサ整合性", cons), ("統合", comb)]:
print(f"{name}: AUC={auc(sc, label):.3f}")
実行結果(seed固定):
生水位の偏差: AUC=0.550
遷移の意外さ: AUC=0.946
センサ整合性: AUC=0.876
統合: AUC=0.996

上段は報告された状態、中段は水位センサ、下段は統合スコアです。中段の水位センサは攻撃中もまったく正常——だから生センサの閾値監視(最下段の数字で0.550、ほぼランダム)は、これらの攻撃を一切捉えられません。一方、下段の統合スコアは3つの攻撃区間すべてで明確に立ち上がっています。

数字の読み取りです。
- 生水位の偏差=0.550:ほぼランダム。攻撃はセンサ値を正常に見せたまま状態だけを偽装したので、連続値監視は無力です。
- 遷移の意外さ=0.946:不正な状態ジャンプ(攻撃2)を鋭く捉え、なりすましの境界も検出します。
- センサ整合性=0.876:「ポンプONと報告しているのに水位が増えない」という物理矛盾(攻撃1・3)を捉えます。
- 統合=0.996:遷移と整合性は異なる攻撃に効くため、両者の最大を取るとほぼ完璧に。状態の文法(遷移)と物理の整合(センサ)を組み合わせるのが核心です。
教訓は明快です。コマンドで動く離散システムでは、センサ値だけ見ていてはステルスな状態偽装を見逃す。アクチュエータの状態遷移という『操作の文法』と、状態-センサの物理整合性をモデル化して初めて、操作チャネルを狙う攻撃が見える。
7. まとめ
コマンドで駆動されるCPS/ICSの異常検知を、アクチュエータ状態遷移モデルで見てきました。
- 核心:アクチュエータを有限状態機械でモデル化し、「コマンド → 状態 → センサ」のつじつまを監視する。
- 遷移の正当性:マルコフ遷移確率で「あり得ない遷移」を検出($-\log P(s_t \mid s_{t-1})$)。
- 整合性:コマンドと実状態、状態とセンサ物理応答の矛盾を残差で捉える。
- 原論文のアーキ:DNN分類器 $f_\theta$ がセンサ $\mathbf{y}$ から「あるべきアクチュエータ状態」 $\hat{\mathbf{a}}$ を予測し、報告状態 $\mathbf{a}$ とのハミング距離 $d_H$ を異常スコアにする。物理式を手書きせずデータ駆動で学び、SWaTでF1=0.96。
- タイミング:滞留時間(dwell time)の異常で固着・遅延を検出。
- 実証:センサ値を正常に見せるステルスな状態なりすましは、生センサ(0.550)には見えないが、状態遷移+整合性(0.996)で捉えられる。
連続値の残差(前記事)と離散状態の遷移(本記事)は、どちらも「操作で動いた分は正常、説明できない部分が異常」という同じ原理の表裏です。次の記事では、もう一段抽象化した「正常な運用文脈への適合性(conformance)」を統計的に測る手法に進みます。

主な参考文献
- R. K. Pandey, T. K. Das, “Anomaly detection in cyber-physical systems using actuator state transition model,” International Journal of Information Technology, vol. 17, pp. 1509–1521, 2025. DOI: 10.1007/s41870-024-02128-x.
- J. Goh, S. Adepu, et al., “A Dataset to Support Research in the Design of Secure Water Treatment Systems (SWaT),” CRITIS, 2016.
- R. Taormina, S. Galelli, et al., “Battle of the Attack Detection Algorithms (BATADAL),” J. Water Resources Planning and Management, 2018.
- C. G. Cassandras, S. Lafortune, “Introduction to Discrete Event Systems,” Springer, 2008.(離散事象システム/FSM)