SPSS Modelerで時系列データをつかった故障分析②故障予知

SPSS Modelerで時系列データをつかった故障予知を行います。
以前公開した[SPSS Modelerで故障予知](https://qiita.com/kawada2017/items/0b04d5116bcc4b6ea9f6)では、あらかじめ時系列データを予測用に加工していました。今回はすこしレベルアップして以下の2本の記事に分けて、未加工の時系列のデータから故障分析をしてみたいと思います。

[①試行錯誤をしながらデータ探索](https://qiita.com/kawada2017/items/7b4d29fe4a48a4afd779)
②時系列データを加工しながら、故障予知（本記事）

この記事は②を行っていきます。
ノードがどのパレットにあるかなどの説明は省きます。


### 実行環境
Modeler 18.2.1
Windows 10 64bit

### 利用データと完成ストリーム
以下からダウンロードしてください。
https://github.com/hkwd/200414FailureAnalysisWithTimeSeries/archive/master.zip

学習データ：Cond4n_e.csv
スコアリングデータ：Cond4n_e104.csv
参照ストリーム:05explore_machineerr.str
完成ストリーム：04transform_machineerr5.str

# データの読み込み
ドラッグアンドドロップでCond4n_e.csvをキャンバスに置き、Cond4n_e.csvのノードをダブルクリックし、可変長インプットノードのプロパティを開き、データのタブを開き、M_CDとERR_CDの「上書き」にチェックをつけ、「ストーレジ」を整数から文字型に変更します。
Cond4n_e.csvのノードのプロパティは「OK」で閉じてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/070126b0-9701-2021-e562-ce93b2bc0905.png)

テーブル」ノードを接続し「実行」してみます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/94d86fa2-44c7-3eb5-5cac-3cd795b106c3.png)


以下のようなデータが表示されます。各列の意味は以下でした。
M_CD: マシンコード
UP_TIIME: 起動時間
POWER: 電力
TEMP: 温度
ERR_CD: エラーコード

M_CDとERR_CDは左寄せの文字型で表示されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/dae8ef45-f9e4-76a6-f55d-ffb518156b5a.png)

# データのソート

もう一度テーブルノードを実行してみます。
少し下までスクロールしてみると85行目でM_CDが変わり、UP_TIMEが0になっていることがわかります。
各マシンの毎にPOWER、TEMP、ERR_CDが時系列に入っているデータということです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/da575ef8-b3ee-5e43-d1e4-141e08f84688.png)

時系列データの加工をする場合には時系列が正しく並んでいる必要があります。このデータは正しくソートされていそうですが、念のためM_CD、UP_TIMEでソートをします。
ソートノードを接続し、ダブルクリックしてプロパティを開きます。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/7d1cb996-4357-268c-bdde-298906c9d29e.png)

「理想可能なフィールドの設定から取得」ボタンでM_CD、UP_TIMEの列を選択し、昇順になっていることを確認し、「OK」で閉じます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/6e79e4f2-ef2c-2468-7a41-231b81633b83.png)

# 目的変数（ラベル）の作成
前回[①試行錯誤をしながらデータ探索](https://qiita.com/kawada2017/items/7b4d29fe4a48a4afd779)の最後にERR_CDを目的変数にモデルをつくるだけだと予測にはあまり使えないという話をしました。

前回作成した05explore_machineerr.strを開いて、モデルのM_CD=104の出力結果を見てみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/30c6eb9e-1a5d-d047-1ac5-0d6b7cbad866.png)

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/2060b700-98bb-7289-9474-4e45ae34d669.png)

このデータを見るとM_CD=104のマシンは43時間目で101のエラーが発生しています。しかしモデル（$R-ERR_CD列）が101のエラーを判別できたのは59時間目です。
故障を予知するということは、モデルは実際の発生よりも前にエラーが発生することを予測しなければ意味がありません。

事前に予測ができれば、点検や部品交換などをおこなってエラーを回避することができれるかもしれません。では何時間前に予測できれば良いのでしょうか？
これはデータを見るだけではわかりません。業務担当者と話をして何時間前に予測ができれば対処が可能かを話して決めることになります。

ここでは5時間前にわかればよいと想定して分析を進めます。
05explore_machineerr.strは閉じて、先ほど作成していたストリームに戻ってください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/02103c05-f72e-37b8-0be6-2006464eb216.png)


5時間前にエラーが発生することを予測するためにはどうすればよいでしょうか？
それには5時間後のエラーコードを目的変数にするという方法があります。この変数は元データにはないので新たに生成します。
フィールド作成ノードを接続し、ダブルクリックしてプロパティを開きます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/f436975a-0d4e-e4a9-5b69-9e9964f9b167.png)

「派生フィールド」名に「ERR_CD_5FUTURE」という名前を指定します。
そして「派生」で「条件付き」を選択します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/2b922ad2-6e6b-bacf-a48c-59df4476291c.png)

そして
IF: `M_CD = @OFFSET(M_CD,-5)`
Then: `@OFFSET(ERR_CD,-5)`
Else: `undef`
を設定します。
`@OFFSET`という関数は現在処理している行の前や後の行を参照するという関数です。
M_CD が5行先と同じ場合に5行先のERR_CDを設定する、M_CD が5行先と違う場合はNULL（undef)を設定するという意味です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/e4bd286f-4779-d5e8-9a18-6d58b831131f.png)

OKで閉じてください。

少し難しいのでデータを見てみましょう。

101のエラーの発生しているM_CD=104のデータを見てみましょう。
レコード設定タブから、条件抽出ノードを接続し、`M_CD='104'`を入力し、OKで閉じてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/96a7b016-ebf7-5fe6-b030-49f56d5c0c12.png)

「テーブル」ノードを接続し実行してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/16c1dde0-35a6-b108-886c-6703c495b45a.png)



43時間目に101のエラーが発生していますが、新しく生成したERR_CD_5FUTUREには38時間目から101のデータが入っています。`@OFFSET`を使うことで5行後ろのデータを持ってきたのです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/e9dcc257-5597-9ed3-a0ce-c588a8a82299.png)

次に一番下までスクロールしてください。ERR_CD_5FUTUREの最後の5行は`$null$`になっています。これは5時間先のエラーコードのデータがそもそも存在しないということです。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/3544523e-285e-be2b-1661-a5ef6e6ac23b.png)

これらのデータは予測には使えませんので削除します。
ERR_CD_5FUTUREが`$null$`のセルを選び、「生成」のメニューから「条件抽出ノード（AND）」を選び、テーブルノードは赤い×ボタンで閉じてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/ed5d19ce-35ab-f1e1-1474-3e99be25b9ca.png)

キャンバスの左上に自動生成された条件抽出ノードがありますので、ダブルクリックしてプロパティを開きます。
以下のように自動的にERR_CD_5FUTUREが`$null$`のレコードを見つける条件が生成されています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/40e9a981-3711-8233-a809-61add45f60ad.png)

「モード」を「破棄」にします。ERR_CD_5FUTUREが`$null$`のレコードを破棄するという意味になります。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/cba56c84-1a95-90b2-fc50-f97cef98c60c.png)

ノードの名前が「（生成）」のままだとわかりにくいので、注釈のタブに移り、「名前」をユーザー設定にし、「NULLの目的変数除去」と入力し、OKで閉じてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/5f74f88c-0083-8e0c-57e4-d3ac14c693ce.png)

「ERR_CD_5FUTURE」のフィールド作成ノードと「M_CD='104'」の条件抽出ノードの間に接続し、テーブルノードを実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/d9439849-2d6c-30cc-dd28-d0db5aa2a668.png)

ERR_CD_5FUTUREが`$null$`の行が削除されたことが確認できました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/e924dbd8-8993-cb0f-d807-9214fab80121.png)

赤い×ボタンで閉じてください。

# 予測モデル作成１
では、今作成した「ERR_CD_5FUTURE」を目的変数として予測モデルを作ってみましょう。
「NULLの目的変数除去」ノードにデータ型ノードを接続し、プロパティで「値の読み込み」ボタンをクリックしてから、以下のように設定します。
「ERR_CD」を対象ではなく、新たに生成した「ERR_CD_5FUTURE」を対象にすることがポイントになります。これで5時間先のエラーが予測対象になりました。OKボタンで閉じます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/16acc9da-6443-d0fd-2644-ef7dde8d6ba0.png)


モデル作成ノードの「CHAID」を接続し、実行してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/d9db6ad4-8102-e7ff-7711-df52bbcf4dac.png)


生成された「ERR_CD_5FUTURE」のモデルナゲットに先ほど作った「M_CD='104'」の条件抽出ノードとテーブルノードを接続します。そして、テーブルノードを実行してください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/6f45a83b-2b29-7bba-a87d-5d0d15f66e52.png)

実際のエラーが発生する5時間前の38時間目の時点で「$R-ERR_CD_5FUTURE」で101のエラーが予測できています。このモデルであれば故障の”予知”が可能です。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/f5093a1f-0c51-24aa-a193-5b7f1ac0c2a8.png)
赤い×ボタンで閉じてください。
モデルの性能を精度で確認してみます。
「精度分析」ノードを接続して、実行してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/7e77f69c-4bc7-d865-0a1c-0425e3a74dbf.png)

精度は93.86%でした。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/e80ffa38-7357-0a5e-d51d-e2dbdd42fc2f.png)

# 特徴量抽出
もう少し性能を上げてみたいと思います。

[前回](https://qiita.com/kawada2017/items/7b4d29fe4a48a4afd779#%E3%83%87%E3%83%BC%E3%82%BF%E3%81%AE%E6%8E%A2%E7%B4%A2)以下のようなグラフを書いて、時間経過とともに温度が上がっていることがわかっていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/26759e28-9087-eb4f-9659-0fedf0b57251.png)

データ型ノードのプロパティを改めて見てみるとこのモデルはある時間のPOWERとTEMPからのみERR_CD_5FUTUREを判別しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/0655ad3a-96f3-fd0e-5ace-c3aa3f7f1ae1.png)

つまりデータの前後関係はみていないということになります。

データを見てみましょう。
レコード設定タブから、条件抽出ノードを接続し、`M_CD='1001'`を入力し、OKで閉じてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/b79c0b1d-0edb-d3f5-3f83-577ee0d36311.png)

テーブルノードを実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/191e97a1-4938-07c5-cf11-2418c504f25f.png)



以下の例なら63時間目にPOWER=886ワットとTEMP=251度という条件だけで101エラーが発生すると誤判別しています。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/f0f3aee2-f087-8877-5209-0d772e029489.png)


時系列データはその変化を新しい特徴量として加工することでより説明力を高めることができます。
データの差をとったり、移動平均をとってならすことで多少のブレを吸収したりすることができます。


では、まず差分をとってみます。
ソートノードとERR_CD_5FUTUREのフィールド作成ノードの間を広げて、新しいフィールド作成ノードをつなぎます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/c1f906f4-e9e6-6bb6-7348-04edf15ad6c8.png)

ダブルクリックしてプロパティを開きます。
モードを「複数」に設定します。そして、利用可能なフィールドの設定から取得ボタンを押して、POWERとTEMPを選びます。フィールドリストに表示されます。

フィールド名拡張子に「`_DIFF`」を設定します。
そして派生で「条件付き」を選びます。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/63cd3cc8-66e9-0ef3-7b17-200adff0fc45.png)


以下を設定します。
If: `M_CD = @OFFSET(M_CD,1)`
Then: `@DIFF1(@FIELD)`
Else: `undef`

先ほどERR_CD_5FUTUREを生成した時の応用になります。
`@OFFSET`という関数は今いる行の前や後の行を参照するという関数でした。
`@DIFF`は1行前との差分を計算します
`@FIELD`はフィールドリストにあげた複数の変数に対して同じ処理を行うという意味です。
M_CD が1行前と同じ場合にPOWERとTEMPについて1行前との差分を設定し、M_CD が1行前と違う場合はNULL（undef)を設定するという意味です。
設定ができたらOKで閉じてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/2eff9580-ff12-5983-d854-f8c681652e12.png)

テーブルノードを実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/014f3d7b-9e62-6445-4343-a0aa251fb997.png)

POWER_DIFFとTEMP_DIFFという列が生成されています。
1時間目のPOWER_DIFFは1時間目の941ワットから0時間目の945ワットを引いた-4ワットとなっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/8b847b9a-9156-cc77-a40d-a682ba8c3232.png)

次に移動平均の特徴量を生成してみます。
_DIFFのノードをコピーして利用します。
右クリックして、「ノードをコピー」を選んでください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/902732f2-2c3d-5d7e-6814-079567a8864b.png)

そしてキャンバスに貼り付けます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/1de9e548-c838-0863-f4d5-421802a93574.png)


「_DIFF」ノードと「ERR_CD_5FUTURE」ノードの間に入れてから、ダブルクリックしてプロパティを開き、以下を設定します。

フィールド名拡張子：`_5MAVG`

If:`M_CD = @OFFSET(M_CD,4)`
Then:`@MEAN(@FIELD,5)`
Else:`undef`

`@MEAN`はN行前までのデータの平均を計算します

M_CD が4行前と同じ場合に、POWERとTEMPについて自行から4行前までのデータの平均を設定し、M_CD が4行前と違う場合はNULL（undef)を設定するという意味です。
設定ができたらOKで閉じてください。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/082e0bc4-171f-b544-1350-06baa1a4f529.png)

テーブルノードを実行します。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/f13eee21-b4b9-0838-5425-f5d8bb31a3e5.png)

POWER_5MAVGとTEMP_5MAVGという列が生成されています。
4時間目のPOWER_5MAVGは0時間目からの4時間目までの945,941,941,941,940ワットの平均である941.6ワットとなっています。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/7c41a880-a79d-81d3-d760-700f07b26c94.png)

# モデルの再作成
では、これらの新たにつくった特徴量変数をつかってモデルを作り直してみましょう。
まず、データ型ノードをダブルクリックしてプロパティを開きます。

自動的に新たに作った特徴量変数が説明変数として登録されていることを確認したら、OKで閉じてください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/05e20999-f3c8-4707-a645-51858fb49613.png)

モデル作成ノードの「CHAID]を実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/ec905540-eeec-e842-7c67-06a8127f8523.png)

モデル再作成されたのでテーブルノードを実行してみます。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/e0f4ecf4-5d05-d3f0-c4a4-e3d1bd9e2aa5.png)

59時間目からの過去のデータも使うことで、先ほど誤判定をしていた63時間目の予測もうまくいっていました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/b4a4b9e4-9091-8f3b-ad7f-b8e82b5e0934.png)

確認ができたら赤い×ボタンで閉じてください。

精度分析ノードを実行します。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/38acc685-70fd-a650-4402-c8bb6194947f.png)

全体の精度としても、特徴量を作る前の93.86%から95.47％に向上しました。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/1183c43a-07cf-fbf8-442c-67e0e5ff1ce2.png)

# スコアリング
このモデルをつかって、センサーデータを毎時間、判定するスコアリングをしてみます。

ドラッグアンドドロップでCond4n_e104.csvをキャンバスに置き、Cond4n_e104.csvのノードをダブルクリックし、可変長インプットノードのプロパティを開き、データのタブを開き、M_CDとERR_CDの「上書き」にチェックをつけ、「ストーレジ」を整数から文字型に変更します。
Cond4n_e.csvのノードのプロパティは「OK」で閉じてください。


![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/6a871558-2b02-23fa-7a7c-17af897b1d1a.png)

テーブルノードを接続します。もう一つのテーブルノードと区別できるように名前を変えます。ダブルクリックしてプロパティを開いてください。
出力のタブで「出力名」に「ユーザー設定」を選び、「スコアリング」と入力して、実行ボタンをクリックします。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/93d77b09-4f72-59f3-10d4-d5b69ac0b014.png)


M_CD=104のマシンの38時間目の状態で、5時間後の43時間目にエラーが発生するかを予測します。差分や移動平均の特徴量変数をつくるために4時間前の34時間目以降のデータが必要になります。

![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/e458ee7d-3f4a-6d33-ccfc-cc58dd098549.png)

確認ができたら、赤い×ボタンで閉じてください。

「Cond4n_e104.csv」の入力ノードと「スコアリング」のテーブルノードの間に、特徴量変数を作る「ソート」「＿DIFF」「＿５AVG」の3つのノードと「ERR_CD_5FUTURE」のモデルナゲットノードをコピーしてつなぎます。
そして、「スコアリング」のテーブルノードを実行してください。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/9bc59a51-67d8-f989-1303-ffd29b73859d.png)

次のように現在の38時間目の時点ではエラーは起きていませんが、5時間後には101のエラーが発生することを予測しています。5時間の間になんらかの対処を行うことでエラーを回避できるかもしれません。
![image.png](https://qiita-image-store.s3.ap-northeast-1.amazonaws.com/0/223763/6c180cc3-b8d0-1556-e543-b737ca2553f4.png)


# おわりに
2回にわけて、時系列データをつかった故障分析を行いました。試行錯誤をしながらデータを理解し、時系列の前後のレコードを活用することが重要だということがお分かりいただけたかと思います。
SPSS Modelerは、試行錯誤が行いやすく、また`@OFFSET`のような前後のレコードにアクセスする関数があるので、このような分析が行いやすいことを感じていただければ幸いです。



# 参考
#### SPSS Modelerによる製造系データの分析ハンズオン・コンテンツへのリンク - Qiita 

https://qiita.com/kawada2017/items/383a8d1059d008ccfad0