Main Content

3 軸振動データを使用した産業機械での異常検出

この例では、機械学習と深層学習を使用して振動データにおける異常を検出する方法を説明します。例では、産業機械の振動データを使用します。最初に、診断特徴デザイナー アプリを使用して、通常の動作に対応する生の測定値から特徴を抽出します。選択した特徴を使用して、異常検出用の 3 種類のモデル (1 クラス SVM、孤立森、LSTM オートエンコーダー) に学習させます。その後、学習済みの各モデルを使用して、機械が正常に動作しているかどうかを識別します。

データ セット

データ セットには、産業機械からの 3 軸振動測定値が含まれています。データは、定期保守の直前と直後の両方で収集されます。定期保守の後に収集されたデータは、機械の通常の動作状態を表していると見なされます。保守前のデータは、通常状態と異常状態のどちらを表す場合もあります。各軸のデータは別々の列に保存されています。データ セットを保存して解凍し、学習データを読み込みます。

url = 'https://ssd.mathworks.com/supportfiles/predmaint/anomalyDetection3axisVibration/v1/vibrationData.zip';
websave('vibrationData.zip',url);
unzip('vibrationData.zip');
load("MachineData.mat")
trainData
trainData=40×4 table
          ch1                 ch2                 ch3           label 
    ________________    ________________    ________________    ______

    {70000×1 double}    {70000×1 double}    {70000×1 double}    Before
    {70000×1 double}    {70000×1 double}    {70000×1 double}    Before
    {70000×1 double}    {70000×1 double}    {70000×1 double}    Before
    {70000×1 double}    {70000×1 double}    {70000×1 double}    Before
    {70000×1 double}    {70000×1 double}    {70000×1 double}    Before
    {70000×1 double}    {70000×1 double}    {70000×1 double}    Before
    {70000×1 double}    {70000×1 double}    {70000×1 double}    Before
    {70000×1 double}    {70000×1 double}    {70000×1 double}    Before
    {70000×1 double}    {70000×1 double}    {70000×1 double}    Before
    {70000×1 double}    {70000×1 double}    {70000×1 double}    Before
    {70000×1 double}    {70000×1 double}    {70000×1 double}    Before
    {70000×1 double}    {70000×1 double}    {70000×1 double}    Before
    {70000×1 double}    {70000×1 double}    {70000×1 double}    Before
    {70000×1 double}    {70000×1 double}    {70000×1 double}    Before
    {70000×1 double}    {70000×1 double}    {70000×1 double}    Before
    {70000×1 double}    {70000×1 double}    {70000×1 double}    Before
      ⋮

データをより良く理解するために、保守前後のデータを可視化します。アンサンブルの 4 番目のメンバーの振動データをプロットします。2 つの状態のデータが異なって見える点に注意してください。

ensMember = 4;
helperPlotVibrationData(trainData, ensMember)

Figure contains 3 axes objects. Axes object 1 with title Channel 1, xlabel Observations, ylabel Vibration Data contains 2 objects of type line. These objects represent Before, After. Axes object 2 with title Channel 2, xlabel Observations, ylabel Vibration Data contains 2 objects of type line. These objects represent Before, After. Axes object 3 with title Channel 3, xlabel Observations, ylabel Vibration Data contains 2 objects of type line. These objects represent Before, After.

診断特徴デザイナー アプリによる特徴の抽出

生のデータには相関やノイズが多いため、機械学習モデルの学習に生のデータを使用することは、あまり効率的ではありません。診断特徴デザイナーアプリでは、対話的にデータの調査と前処理を行い、時間ドメインと周波数ドメインの特徴を抽出したうえで特徴をランク付けして、どれが故障やその他の異常システムの診断に最も効果的か判定できます。次に関数をエクスポートして、選択した特徴をデータ セットからプログラムにより抽出できます。コマンド プロンプトで「diagnosticFeatureDesigner」と入力して、"診断特徴デザイナー" を開きます。"診断特徴デザイナー" の使用方法のチュートリアルについては、予知保全アルゴリズムの状態インジケーターの設計を参照してください。

[新規セッション] ボタンをクリックし、trainData をソースとして選択してから、label[状態変数] に設定します。変数 label は、対応するデータについて機械の状態を特定します。

"診断特徴デザイナー" を使用して特徴について反復し、それらをランク付けできます。アプリによって、生成されたすべての特徴のヒストグラム ビューが作成され、ラベルごとの分布が可視化されます。たとえば、以下のヒストグラムは、ch1 から抽出した各種の特徴の分布を示しています。これらのヒストグラムは、ラベルグループの分離がわかりやすくなるよう、この例で使用するデータ セットよりもはるかに大規模なデータ セットから導出されたものです。使用するデータ セットは比較的小規模であるため、結果は異なります。

各チャネルにつき上位 4 つのランク付けされた特徴を使用します。

  • ch1: クレスト ファクター、尖度、RMS、標準偏差

  • ch2: 平均、RMS、歪度、標準偏差

  • ch3: クレスト ファクター、SINAD、SNR、THD

特徴を生成するための関数を診断特徴デザイナー アプリからエクスポートして、generateFeatures の名前で保存します。この関数はコマンド ラインから、データ セット全体の各チャネルにつき上位 4 つの関連する特徴を抽出します。

trainFeatures = generateFeatures(trainData);
head(trainFeatures)
    label     ch1_stats/Col1_CrestFactor    ch1_stats/Col1_Kurtosis    ch1_stats/Col1_RMS    ch1_stats/Col1_Std    ch2_stats/Col1_Mean    ch2_stats/Col1_RMS    ch2_stats/Col1_Skewness    ch2_stats/Col1_Std    ch3_stats/Col1_CrestFactor    ch3_stats/Col1_SINAD    ch3_stats/Col1_SNR    ch3_stats/Col1_THD
    ______    __________________________    _______________________    __________________    __________________    ___________________    __________________    _______________________    __________________    __________________________    ____________________    __________________    __________________

    Before              2.2811                      1.8087                   2.3074                2.3071               -0.032332              0.64962                   4.523                  0.64882                    11.973                    -15.945                -15.886                -2.732      
    Before              2.3276                      1.8379                   2.2613                 2.261                -0.03331              0.59458                   5.548                  0.59365                    10.284                    -15.984                -15.927               -2.7507      
    Before              2.3276                      1.8626                   2.2613                2.2612               -0.012052              0.48248                  4.3638                  0.48233                    8.9125                    -15.858                -15.798               -2.7104      
    Before              2.8781                      2.1986                   1.8288                1.8285               -0.005049              0.34984                  2.3324                  0.34981                    11.795                    -16.191                 -16.14               -3.0683      
    Before              2.8911                        2.06                   1.8205                1.8203              -0.0018988              0.27366                  1.7661                  0.27365                    11.395                    -15.947                -15.893               -3.1126      
    Before              2.8979                      2.1204                   1.8163                1.8162              -0.0044174               0.3674                  2.8969                  0.36737                    11.685                    -15.963                -15.908               -2.9761      
    Before              2.9494                        1.92                   1.7846                1.7844              -0.0067284              0.36262                  4.1308                  0.36256                    12.396                    -15.999                -15.942               -2.8281      
    Before              2.5106                      1.6774                   1.7513                1.7511              -0.0089548              0.32348                  3.7691                  0.32335                    8.8808                     -15.79                -15.732               -2.9532      

学習用の完全なデータ セットの準備

ここまでに使用してきたデータ セットは、特徴の抽出と選択の過程を説明するために用いた、はるかに大規模なデータ セットの小さなサブセットに過ぎません。使用可能なすべてのデータでアルゴリズムに学習させると、最良のパフォーマンスがもたらされます。そのために、17,642 の信号からなるより大規模なデータ セットから前もって抽出しておいたものと同じ 12 個の特徴を読み込みます。

load("FeatureEntire.mat")
head(featureAll)
    label     ch1_stats/Col1_CrestFactor    ch1_stats/Col1_Kurtosis    ch1_stats/Col1_RMS    ch1_stats/Col1_Std    ch2_stats/Col1_Mean    ch2_stats/Col1_RMS    ch2_stats/Col1_Skewness    ch2_stats/Col1_Std    ch3_stats/Col1_CrestFactor    ch3_stats/Col1_SINAD    ch3_stats/Col1_SNR    ch3_stats/Col1_THD
    ______    __________________________    _______________________    __________________    __________________    ___________________    __________________    _______________________    __________________    __________________________    ____________________    __________________    __________________

    Before              2.3683                       1.927                   2.2225                2.2225               -0.015149              0.62512                  4.2931                  0.62495                    5.6569                    -5.4476                -4.9977               -4.4608      
    Before               2.402                      1.9206                   2.1807                2.1803               -0.018269              0.56773                  3.9985                  0.56744                    8.7481                    -12.532                -12.419               -3.2353      
    Before              2.4157                      1.9523                   2.1789                2.1788              -0.0063652              0.45646                  2.8886                  0.45642                    8.3111                    -12.977                -12.869               -2.9591      
    Before              2.4595                      1.8205                     2.14                2.1401               0.0017307              0.41418                  2.0635                  0.41418                    7.2318                    -13.566                -13.468               -2.7944      
    Before              2.2502                      1.8609                   2.3391                 2.339              -0.0081829               0.3694                  3.3498                  0.36931                    6.8134                     -13.33                -13.225               -2.7182      
    Before              2.4211                      2.2479                   2.1286                2.1285                0.011139              0.36638                  1.8602                  0.36621                    7.4712                    -13.324                -13.226               -3.0313      
    Before              3.3111                      4.0304                   1.5896                1.5896              -0.0080759              0.47218                  2.1132                  0.47211                    8.2412                     -13.85                -13.758               -2.7822      
    Before              2.2655                      2.0656                   2.3233                2.3233              -0.0049447              0.37829                  2.4936                  0.37827                    7.6947                    -13.781                -13.683               -2.5601      

cvpartition を使用して、データを学習セットと、独立したテスト セットに分割します。補助関数 helperExtractLabeledData を使用して、変数 featureTrain 内でラベル 'After' に対応する特徴をすべて検索します。

rng(0) % set for reproducibility
idx = cvpartition(featureAll.label, 'holdout', 0.1);
featureTrain = featureAll(idx.training, :);
featureTest = featureAll(idx.test, :);

それぞれのモデルでは、通常状態であると見なされる、保守後のデータのみで学習を行います。このデータのみを featureTrain から抽出します。

trueAnomaliesTest = featureTest.label;
featureNormal = featureTrain(featureTrain.label=='After', :);

1 クラス SVM による異常の検出

サポート ベクター マシンは強力な分類器であり、ここでは通常状態のデータのみで学習するバリアントが使用されています。このモデルは、通常状態のデータから "かけ離れた" 異常の識別に効果的です。関数 fitcsvm と通常状態のデータを使用して、1 クラス SVM モデルに学習させます。

mdlSVM = fitcsvm(featureNormal, 'label', 'Standardize', true, 'OutlierFraction', 0);

通常状態と異常状態の両方のデータを含むテスト データを使用して、学習済みの SVM モデルを検証します。

featureTestNoLabels = featureTest(:, 2:end);
[~,scoreSVM] = predict(mdlSVM,featureTestNoLabels);
isanomalySVM = scoreSVM<0;
predSVM = categorical(isanomalySVM, [1, 0], ["Anomaly", "Normal"]);
trueAnomaliesTest = renamecats(trueAnomaliesTest,["After","Before"], ["Normal","Anomaly"]);
figure;
confusionchart(trueAnomaliesTest, predSVM, Title="Anomaly Detection with One-class SVM", Normalization="row-normalized");

Figure contains an object of type ConfusionMatrixChart. The chart of type ConfusionMatrixChart has title Anomaly Detection with One-class SVM.

混同行列から、1 クラス SVM がうまく機能していることがわかります。異常状態のサンプルの 0.3% のみが通常として誤分類され、通常状態のデータの約 0.9% が異常として誤分類されています。

孤立森による異常の検出

孤立森の決定木では、各観測を 1 枚の葉に分離します。サンプルがその葉に至るためにいくつの判定を通過するかは、それを他から分離するのがどの程度困難であったかの尺度です。特定サンプルの木の平均深度は異常のスコアとして使用され、iforest によって返されます。

通常状態のデータのみで孤立森モデルに学習させます。

[mdlIF,~,scoreTrainIF] = iforest(featureNormal{:,2:13},'ContaminationFraction',0.09);

テスト データを使用して、学習済みの孤立森モデルを検証します。混同チャートを使用して、このモデルのパフォーマンスを可視化します。

[isanomalyIF,scoreTestIF] = isanomaly(mdlIF,featureTestNoLabels.Variables);
predIF = categorical(isanomalyIF, [1, 0], ["Anomaly", "Normal"]);
figure;
confusionchart(trueAnomaliesTest,predIF,Title="Anomaly Detection with Isolation Forest",Normalization="row-normalized");

Figure contains an object of type ConfusionMatrixChart. The chart of type ConfusionMatrixChart has title Anomaly Detection with Isolation Forest.

このデータでは、孤立森は 1 クラス SVM ほどうまく機能しません。機能が低下する理由は、学習データには通常状態のデータのみが含まれており、一方でテスト データには約 30% の異常状態のデータが含まれている点にあります。したがって、学習データとテスト データの両方において、通常状態のデータに対する異常状態のデータの割合が同程度である場合には、孤立森モデルの方が適切な選択となります。

LSTM オートエンコーダー ネットワークによる異常の検出

オートエンコーダーはニューラル ネットワークの一種で、ラベルなしのデータの圧縮表現を学習します。LSTM オートエンコーダーはこのネットワークから派生したもので、シーケンス データの圧縮表現を学習できます。ここでは、通常状態のデータのみを使って LSTM オートエンコーダーに学習させ、この学習済みのネットワークを使用して、通常状態には見えない信号を特定します。

まず、保守後のデータから特徴を抽出します。

featuresAfter = helperExtractLabeledData(featureTrain, ...
   "After");

LSTM オートエンコーダー ネットワークを構成し、学習オプションを設定します。

featureDimension = 1;

% Define biLSTM network layers
layers = [ sequenceInputLayer(featureDimension)
   bilstmLayer(16)
   reluLayer
   bilstmLayer(32)
   reluLayer
   bilstmLayer(16)
   reluLayer
   fullyConnectedLayer(featureDimension)];

% Set Training Options
options = trainingOptions('adam', ...
   'Plots', 'training-progress', ...
   'Metrics', 'rmse', ...
   'MiniBatchSize', 500,...
   'MaxEpochs',200);

学習オプション パラメーター MaxEpochs は 200 に設定されます。検証の精度を高めるには、このパラメーターをより大きい数に設定することができます。ただし、ネットワークが過適合になる可能性があります。

trainnet を使用してモデルを学習させ、損失関数として平均二乗誤差 (mse) を指定します。

net = trainnet(featuresAfter, featuresAfter, layers, "mse", options);
    Iteration    Epoch    TimeElapsed    LearnRate    TrainingLoss    TrainingRMSE
    _________    _____    ___________    _________    ____________    ____________
            1        1       00:00:09        0.001          33.771          5.8113
           50        3       00:00:15        0.001          29.543          5.4353
          100        5       00:00:19        0.001          15.904           3.988
          150        8       00:00:24        0.001          18.274          4.2748
          200       10       00:00:29        0.001          12.052          3.4716
          250       13       00:00:33        0.001          15.794          3.9742
          300       15       00:00:38        0.001          10.051          3.1703
          350       18       00:00:42        0.001           13.84          3.7202
          400       20       00:00:47        0.001           8.359          2.8912
          450       23       00:00:51        0.001          12.185          3.4907
          500       25       00:00:55        0.001          7.1721          2.6781
          550       28       00:01:00        0.001          11.018          3.3194
          600       30       00:01:04        0.001          6.2384          2.4977
          650       33       00:01:08        0.001          10.009          3.1637
          700       35       00:01:12        0.001          5.3576          2.3146
          750       38       00:01:16        0.001          8.8568           2.976
          800       40       00:01:20        0.001          4.5712           2.138
          850       43       00:01:24        0.001          8.0863          2.8436
          900       45       00:01:28        0.001          4.0192          2.0048
          950       48       00:01:32        0.001           7.456          2.7306
         1000       50       00:01:36        0.001          3.6334          1.9061
         1050       53       00:01:41        0.001          6.9985          2.6455
         1100       55       00:01:45        0.001           3.332          1.8254
         1150       58       00:01:49        0.001          6.5709          2.5634
         1200       60       00:01:53        0.001          3.0456          1.7452
         1250       63       00:01:57        0.001          6.2219          2.4944
         1300       65       00:02:00        0.001          2.8124           1.677
         1350       68       00:02:04        0.001           5.868          2.4224
         1400       70       00:02:08        0.001          2.4919          1.5786
         1450       73       00:02:12        0.001          5.3488          2.3127
         1500       75       00:02:16        0.001           2.161            1.47
         1550       78       00:02:20        0.001          4.9866          2.2331
         1600       80       00:02:24        0.001          1.9088          1.3816
         1650       83       00:02:28        0.001          4.6791          2.1631
         1700       85       00:02:32        0.001          1.7001          1.3039
         1750       88       00:02:36        0.001          4.4113          2.1003
         1800       90       00:02:41        0.001          1.5254          1.2351
         1850       93       00:02:45        0.001          4.1853          2.0458
         1900       95       00:02:49        0.001          1.3738          1.1721
         1950       98       00:02:53        0.001          3.9576          1.9894
         2000      100       00:02:57        0.001          1.2387           1.113
         2050      103       00:03:01        0.001          3.7698          1.9416
         2100      105       00:03:05        0.001           1.123          1.0597
         2150      108       00:03:09        0.001          3.6016          1.8978
         2200      110       00:03:13        0.001          1.0263          1.0131
         2250      113       00:03:17        0.001          3.4534          1.8583
         2300      115       00:03:21        0.001         0.94179         0.97046
         2350      118       00:03:25        0.001          3.3239          1.8232
         2400      120       00:03:29        0.001         0.87847         0.93727
         2450      123       00:03:34        0.001          3.2066          1.7907
         2500      125       00:03:38        0.001         0.80876         0.89931
         2550      128       00:03:42        0.001          3.0997          1.7606
         2600      130       00:03:46        0.001         0.74998         0.86601
         2650      133       00:03:50        0.001          3.0022          1.7327
         2700      135       00:03:54        0.001         0.70011         0.83672
         2750      138       00:03:58        0.001          2.9062          1.7047
         2800      140       00:04:02        0.001          0.6546         0.80908
         2850      143       00:04:05        0.001          2.8237          1.6804
         2900      145       00:04:09        0.001          0.6157         0.78466
         2950      148       00:04:13        0.001          2.7403          1.6554
         3000      150       00:04:18        0.001          0.5843          0.7644
         3050      153       00:04:22        0.001           2.665          1.6325
         3100      155       00:04:25        0.001         0.54377         0.73741
         3150      158       00:04:29        0.001          2.5921            1.61
         3200      160       00:04:33        0.001         0.51321         0.71639
         3250      163       00:04:37        0.001          2.5235          1.5886
         3300      165       00:04:41        0.001         0.49071         0.70051
         3350      168       00:04:45        0.001          2.4591          1.5682
         3400      170       00:04:49        0.001         0.46161         0.67942
         3450      173       00:04:53        0.001          2.3967          1.5481
         3500      175       00:04:57        0.001         0.43363         0.65851
         3550      178       00:05:01        0.001          2.3392          1.5295
         3600      180       00:05:05        0.001         0.41236         0.64215
         3650      183       00:05:09        0.001          2.2851          1.5116
         3700      185       00:05:13        0.001         0.39331         0.62715
         3750      188       00:05:17        0.001           2.234          1.4947
         3800      190       00:05:21        0.001         0.37487         0.61227
         3850      193       00:05:24        0.001          2.1853          1.4783
         3900      195       00:05:28        0.001         0.35768         0.59806
         3950      198       00:05:32        0.001          2.1387          1.4624
         4000      200       00:05:36        0.001         0.34181         0.58465
Training stopped: Max epochs completed

検証データでのモデル動作と誤差の可視化

異常状態と通常状態からそれぞれ 1 つのサンプルを抽出し、可視化します。以下のプロットでは、12 個の特徴 (X 軸上に表示) それぞれについて、オートエンコーダー モデルの再構成誤差を示しています。このプロットでは、再構成された特徴値は "Decoded" (復号化された) 信号と呼ばれています。このサンプルでは、特徴 10、11、12 が異常入力に対してうまく再構成されず、したがって、誤差が大きくなります。再構成誤差を使用して異常を特定できます。

testNormal = featureTest(1200, 2:end).Variables';
testAnomaly = featureTest(200, 2:end).Variables';

% Predict decoded signal for both
decodedNormal = predict(net,testNormal);
decodedAnomaly = predict(net,testAnomaly);

% Visualize
helperVisualizeModelBehavior(testNormal, testAnomaly, decodedNormal, decodedAnomaly)

Figure contains 2 axes objects. Axes object 1 with title Normal Input, ylabel Error contains an object of type stem. These objects represent Input, Decoded, Error. Axes object 2 with title Abnormal Input, ylabel Error contains an object of type stem. These objects represent Input, Decoded, Error.

すべての通常状態のデータと異常状態のデータの特徴を抽出します。学習済みオートエンコーダー モデルを使用して、保守前と保守後の両方のデータについて、選択した 12 個の特徴を予測します。以下のプロットは、12 個の特徴の平方根平均二乗再構成誤差を示したものです。図には、異常状態のデータの再構成誤差が通常状態のデータよりはるかに高いことが示されています。オートエンコーダーは通常状態のデータで学習したため、類似する信号をよりうまく再構成するという結果は予想どおりです。

% Extract data Before maintenance
XTestBefore = helperExtractLabeledData(featureTest, "Before");

% Predict output before maintenance and calculate error
yHatBefore = minibatchpredict(net, XTestBefore, 'UniformOutput', false);
errorBefore = helperCalculateError(XTestBefore, yHatBefore);

% Extract data after maintenance
XTestAfter = helperExtractLabeledData(featureTest, "After");

% Predict output after maintenance and calculate error
yHatAfter = minibatchpredict(net, XTestAfter, 'UniformOutput', false);
errorAfter = helperCalculateError(XTestAfter, yHatAfter);

helperVisualizeError(errorBefore, errorAfter);

Figure contains 2 axes objects. Axes object 1 with xlabel Observations, ylabel Reconstruction Error contains an object of type line. Axes object 2 with xlabel Observations, ylabel Reconstruction Error contains an object of type line.

異常の特定

検証データ全体について、再構成誤差を計算します。

XTestAll = helperExtractLabeledData(featureTest, "All");

yHatAll = minibatchpredict(net, XTestAll, 'UniformOutput', false);
errorAll = helperCalculateError(XTestAll, yHatAll);

再構成誤差がすべての観測の平均の 0.5 倍となっている点を異常と定義します。このしきい値は前回の実験を通して決定されたものであり、必要に応じて変更することができます。

thresh = 0.5;
anomalies = errorAll > thresh*mean(errorAll);

helperVisualizeAnomalies(anomalies, errorAll, featureTest);

Figure contains an axes object and an object of type ConfusionMatrixChart. The axes object with xlabel Observation, ylabel Reconstruction Error contains 2 objects of type line. One or more of the lines displays its values using only markers These objects represent Error, Candidate Anomaly.

この例では、3 種類のモデルを使用して異常を検出しています。テスト データの異常検出は、1 クラス SVM が 99.7% と最も高いパフォーマンスを示し、他の 2 つのモデルは 93% 程度の精度でした。モデルの相対的なパフォーマンスは、別の特徴セットを選択した場合や、各モデルに別のハイパーパラメーターを使用した場合に変化する可能性があります。診断特徴デザイナー MATLAB アプリを使用して、さらに特徴選択を試してみましょう。

サポート関数

function E = helperCalculateError(X, Y)
% HELPERCALCULATEERROR calculates the rms error value between the
% inputs X, Y
E = zeros(length(X),1);
for i = 1:length(X)
   E(i,:) = sqrt(sum((Y{i} - X{i}).^2));
end

end

function helperVisualizeError(errorBefore, errorAfter)
% HELPERVISUALIZEERROR creates a plot to visualize the errors on detecting
% before and after conditions
figure("Color", "W")
tiledlayout("flow")

nexttile
plot(1:length(errorBefore), errorBefore, 'LineWidth',1.5), grid on
title(["Before Maintenance", ...
   sprintf("Mean Error: %.2f\n", mean(errorBefore))])
xlabel("Observations")
ylabel("Reconstruction Error")
ylim([0 15])

nexttile
plot(1:length(errorAfter), errorAfter, 'LineWidth',1.5), grid on,
title(["After Maintenance", ...
   sprintf("Mean Error: %.2f\n", mean(errorAfter))])
xlabel("Observations")
ylabel("Reconstruction Error")
ylim([0 15])

end

function helperVisualizeAnomalies(anomalies, errorAll, featureTest)
% HELPERVISUALIZEANOMALIES creates a plot of the detected anomalies
anomalyIdx = find(anomalies);
anomalyErr = errorAll(anomalies);

predAE = categorical(anomalies, [1, 0], ["Anomaly", "Normal"]);
trueAE = renamecats(featureTest.label,["Before","After"],["Anomaly","Normal"]);

acc = numel(find(trueAE == predAE))/numel(predAE)*100;
figure;
t = tiledlayout("flow");
title(t, "Test Accuracy: " + round(mean(acc),2) + "%");
nexttile
hold on
plot(errorAll)
plot(anomalyIdx, anomalyErr, 'x')
hold off
ylabel("Reconstruction Error")
xlabel("Observation")
legend("Error", "Candidate Anomaly")

nexttile
confusionchart(trueAE,predAE)

end

function helperVisualizeModelBehavior(normalData, abnormalData, decodedNorm, decodedAbNorm)
%HELPERVISUALIZEMODELBEHAVIOR Visualize model behavior on sample validation data

figure("Color", "W")
tiledlayout("flow")

nexttile()
hold on
colororder('default')
yyaxis left
plot(normalData')
plot(decodedNorm',":","LineWidth",1.5)
hold off
title("Normal Input")
grid on
ylabel("Feature Value")
yyaxis right
stem(abs(normalData' - decodedNorm'))
ylim([0 2])
ylabel("Error")
legend(["Input", "Decoded","Error"],"Location","southwest")

nexttile()
hold on
yyaxis left
plot(abnormalData)
plot(decodedAbNorm',":","LineWidth",1.5)
hold off
title("Abnormal Input")
grid on
ylabel("Feature Value")
yyaxis right
stem(abs(abnormalData' - decodedAbNorm'))
ylim([0 2])
ylabel("Error")
legend(["Input", "Decoded","Error"],"Location","southwest")

end

function X = helperExtractLabeledData(featureTable, label)
%HELPEREXTRACTLABELEDDATA Extract data from before or after operating
%conditions and re-format to support input to autoencoder network

% Select data with label After
if label == "All"
   Xtemp = featureTable(:, 2:end).Variables;
else
   tF = featureTable.label == label;
   Xtemp = featureTable(tF, 2:end).Variables;
end

% Arrange data into cells
X = cell(length(Xtemp),1);
for i = 1:length(Xtemp)
   X{i,:} = Xtemp(i,:)';
end

end

参考

| | |

関連するトピック