運転条件正規化による劣化検知:運転条件で割って劣化だけを取り出す(PHM/C-MAPSS)

前記事のSong+ 2007は、環境(操作)を条件にして異常を測る考え方でした。

画像なし
条件付き異常検知の原型(Song+ 2007)
環境属性で条件づける考え方。本記事はそのもっとも実務的な実装です。

この記事は、その「条件付き」を、機器の健全性監視(PHM, Prognostics and Health Management)でもっとも泥臭く・もっとも効く形で使う運転条件正規化(operating-condition normalization)を扱います。

問題はこうです。回転機械やエンジンのセンサ値は、運転条件(回転数・負荷・出力)で大きく変わります。一方で、私たちが検出したいのは、ゆっくり進む劣化です。ところがセンサ値は「運転条件の効果」と「劣化の効果」が混ざっているため、運転条件が変わるたびにセンサが激しく上下し、劣化の小さな信号は完全に埋もれてしまいます。

運転条件正規化の概念図

解決策はシンプルです。運転条件をクラスタリングし、条件ごとに別々の平均・分散で正規化する。条件で説明できる変動を取り除けば、残るのは劣化だけ。これは「操作・運転で動いた分を異常としない」という本シリーズの原理の、PHM版です。

この手法が効く場面は明確です。

  • 可変運転の回転機械・エンジン:回転数や負荷が運転中に変わる設備
  • 負荷追従運転の発電・プラント:運転点が需要で動く系
  • 残存有用寿命(RUL)予測の前処理:劣化トレンドを抽出する第一歩

この記事の内容

  • なぜ生センサでは劣化が見えないのか — 条件効果による埋没
  • 運転条件のクラスタリング
  • 条件別正規化 — 条件ごとの平均・分散で標準化
  • C-MAPSS(NASAターボファン)の6運転条件
  • NumPy実装 — 生センサ(AUC0.63)に対し条件別正規化(0.998)が劣化を捉える様子を実測

前提知識

マハラノビス距離による異常検知
健全性指標の考え方の土台です。
運用・操作で動くシステムの異常検知:サーベイ(親記事)
条件付き・マルチモードの全体像。

1. なぜ生センサでは劣化が見えないのか

ターボファンエンジンのような機器を考えます。各時刻のセンサ値は、ざっくり次のように書けます。

$$ \begin{equation} x_t = \underbrace{g(\text{運転条件}_t)}_{\text{大きく変動}} + \underbrace{d(\text{劣化}_t)}_{\text{小さく単調増加}} + \text{雑音} \end{equation} $$

運転条件の効果 $g$ は大きく、劣化の効果 $d$ は小さくゆっくり。生センサを時系列で見ると、運転条件が切り替わるたびに大ジャンプし、劣化のトレンドはまったく見えません。

1ユニットの生センサ:運転条件で激しく上下し劣化が見えない

上図は1台の機器の生センサです。色が運転条件を表します。条件が変わるたびにセンサ値が上下に飛び、寿命末期に向かうはずの劣化トレンドは完全に埋没しています。これでは健全性を測れません。

まず、運転条件そのものを識別する必要があります。


2. 運転条件のクラスタリング

運転条件は、運転設定変数(高度・速度・出力指令など)で表されます。これらをクラスタリングすれば、各時刻がどの運転条件に属するかが分かります。

運転条件のクラスタリング

C-MAPSSのFD002/FD004では、運転設定が明確に6つのクラスタに分かれます。$k$-meansやGMMで簡単に識別できます。各時刻にクラスタ番号(運転条件ラベル)を付与すれば、次の正規化の準備が整います。


3. 条件別正規化

ここが核心です。普通の標準化は全データの平均・分散で割りますが、条件別正規化は運転条件ごとに別々の平均・分散で割ります

条件別正規化の式

$$ \begin{equation} z = \frac{x – \mu_{\text{cond}}}{\sigma_{\text{cond}}} \end{equation} $$

ここで $\mu_{\text{cond}}, \sigma_{\text{cond}}$ は、その時刻の運転条件における正常(新品付近)データの平均・分散です。条件ごとに別々に学習します。

こうすると、運転条件の効果 $g(\text{運転条件})$ は条件別の平均 $\mu_{\text{cond}}$ にちょうど吸収され、引き算で消えます。残るのは劣化の効果と雑音だけ。

条件別正規化後:劣化トレンドが明確に出る

正規化後の健全性指標(正規化センサのノルム)を見ると、図2では完全に埋もれていた劣化の単調増加トレンドが、くっきり現れます。真の劣化(赤破線)とよく一致しています。条件で割るだけで、見えなかった劣化が見える——これが運転条件正規化の威力です。

C-MAPSSベンチマーク

この手法が広く使われるのが、NASAのC-MAPSS(ターボファンエンジン劣化シミュレーション)ベンチマークです。FD001・FD003は運転条件が1つですが、FD002・FD004は6運転条件を持ち、条件正規化なしでは劣化と条件変化が混ざって扱えません。残存有用寿命(RUL)予測研究の定番前処理です。実装で効果を測ります。


4. NumPy実装 — 条件で割って劣化を取り出す

多数の機器を寿命まで運転するデータを作ります。各時刻の運転条件(6種)でセンサ基準が変わり、劣化が単調に進みます。

import numpy as np
rng = np.random.default_rng(0)
n_units, n_cond = 80, 6
cond_offsets = rng.normal(0, 3.0, (n_cond, 3))      # 6条件×3センサ の基準ずれ(大)
cond_scales  = rng.uniform(0.8, 1.4, (n_cond, 3))
rows = []
for u in range(n_units):
    life = rng.integers(120, 260)
    for t in range(life):
        cond = rng.integers(n_cond)
        health = 1.0 - t/life                        # 1(新品)→0(寿命)
        deg = (1 - health)**1.3                       # 劣化量(単調増)
        base = cond_offsets[cond] + deg*np.array([1.0, -0.8, 1.2])   # 劣化がセンサを動かす
        sensor = base*cond_scales[cond] + rng.normal(0, 0.25, 3)
        rows.append((u, t, life, cond, health, *sensor))
A = np.array(rows)
u=A[:,0].astype(int); t=A[:,1]; life=A[:,2]; cond=A[:,3].astype(int); health=A[:,4]; S=A[:,5:8]
frac = t/life

新品付近(health>0.8)で、運転条件ごとの平均・分散を学習し、条件別正規化します。

train = health > 0.8
mu_c = np.zeros((n_cond,3)); sd_c = np.zeros((n_cond,3))
for k in range(n_cond):
    m = train & (cond==k)
    mu_c[k] = S[m].mean(0); sd_c[k] = S[m].std(0) + 1e-6
Z = (S - mu_c[cond]) / sd_c[cond]            # 条件別正規化
hi_norm = np.linalg.norm(Z, axis=1)          # 健全性指標(新品~0, 劣化で増大)

# 比較: 条件を無視した全体標準化
mu_all = S[train].mean(0); sd_all = S[train].std(0)
hi_raw = np.linalg.norm((S - mu_all)/sd_all, axis=1)

寿命末期(frac>0.7)を「劣化」、新品(frac<0.3)を「健全」として、検知AUCと真の劣化との相関を測ります。

ev = (frac < 0.3) | (frac > 0.7)
label = (frac[ev] > 0.7).astype(int)
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)

print(f"生センサ(条件無視) AUC={auc(hi_raw[ev],label):.3f}  相関={np.corrcoef(hi_raw,1-health)[0,1]:.3f}")
print(f"条件別正規化       AUC={auc(hi_norm[ev],label):.3f}  相関={np.corrcoef(hi_norm,1-health)[0,1]:.3f}")

実行結果(seed固定):

生センサ(条件無視) AUC=0.633  相関=0.151
条件別正規化       AUC=0.998  相関=0.861

複数ユニットの健全性指標

複数の機器の健全性指標を重ねると、生センサ(左)はユニット間でバラバラですが、条件別正規化(右)は全機器が寿命に向かって揃って単調増加します。

健全性指標と劣化の関係

健全性指標の分布とAUC

検知AUCと相関

数字の読み取りです。

  • 劣化検知AUC:0.633 → 0.998:生センサは条件変化に埋もれて劣化をほとんど検出できませんが、条件別正規化でほぼ完璧に。
  • 真の劣化との相関:0.151 → 0.861:健全性指標が真の劣化を正しく追えるようになります。

教訓は明快です。高度なモデルを使う前に、運転条件で割って条件効果を消すだけで、見えなかった劣化が見える。 これは前記事の残差ベース(制御入力で予測して引く)と発想は同じで、ここでは「運転条件で正規化して引く」という形を取っています。


5. まとめ

PHMの実務で必須の運転条件正規化を見てきました。

  • 問題:センサ値は「運転条件の効果+劣化の効果」の和。条件変化が大きく劣化が埋もれる。
  • 解決:運転条件をクラスタリングし、条件ごとの平均・分散で正規化して条件効果を消す。
  • ベンチマーク:C-MAPSS FD002/FD004(6運転条件)。RUL予測の定番前処理。
  • 実証:生センサ(AUC0.63・相関0.15)に対し条件別正規化(0.998・0.86)。

「運転条件で割る」という素朴な操作が、条件付き異常検知のもっとも実務的な姿です。次の記事では、モードラベルが無い場合に変分ベイズでモード数まで自動推定する、より高度なマルチモード手法に進みます。

画像なし
条件付き異常検知の原型(Song+ 2007)
条件付きの理論的基礎。
運用・操作で動くシステムの異常検知:サーベイ(親記事)
全体像と他手法への地図。

主な参考文献

  • A. Saxena, K. Goebel, D. Simon, N. Eklund, “Damage propagation modeling for aircraft engine run-to-failure simulation (C-MAPSS),” Int. Conf. on Prognostics and Health Management (PHM), 2008.
  • F. O. Heimes, “Recurrent neural networks for remaining useful life estimation,” PHM, 2008.
  • E. Ramasso, A. Saxena, “Performance benchmarking and analysis of prognostic methods for CMAPSS datasets,” Int. J. Prognostics and Health Management, 2014.