Main Content

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

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

データ セット

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

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)

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

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

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

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

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

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

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

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

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

trainFeatures = generateFeatures(trainData);
head(trainFeatures)
ans=8×13 table
    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)
ans=8×13 table
    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");

混同行列から、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");

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

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

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

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

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

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

featureDimension = 1;

% Define biLSTM network layers
layers = [ sequenceInputLayer(featureDimension, 'Name', 'in')
   bilstmLayer(16, 'Name', 'bilstm1')
   reluLayer('Name', 'relu1')
   bilstmLayer(32, 'Name', 'bilstm2')
   reluLayer('Name', 'relu2')
   bilstmLayer(16, 'Name', 'bilstm3')
   reluLayer('Name', 'relu3')
   fullyConnectedLayer(featureDimension, 'Name', 'fc')
   regressionLayer('Name', 'out') ];

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

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

モデルに学習させます。

net = trainNetwork(featuresAfter, featuresAfter, layers, options);
Training on single CPU.
|========================================================================================|
|  Epoch  |  Iteration  |  Time Elapsed  |  Mini-batch  |  Mini-batch  |  Base Learning  |
|         |             |   (hh:mm:ss)   |     RMSE     |     Loss     |      Rate       |
|========================================================================================|
|       1 |           1 |       00:00:05 |         5.81 |         16.9 |          0.0010 |
|       3 |          50 |       00:00:17 |         5.43 |         14.8 |          0.0010 |
|       5 |         100 |       00:00:28 |         3.99 |          7.9 |          0.0010 |
|       8 |         150 |       00:00:39 |         4.27 |          9.1 |          0.0010 |
|      10 |         200 |       00:00:51 |         3.48 |          6.1 |          0.0010 |
|      13 |         250 |       00:01:02 |         3.97 |          7.9 |          0.0010 |
|      15 |         300 |       00:01:13 |         3.17 |          5.0 |          0.0010 |
|      18 |         350 |       00:01:25 |         3.72 |          6.9 |          0.0010 |
|      20 |         400 |       00:01:37 |         2.89 |          4.2 |          0.0010 |
|      23 |         450 |       00:01:49 |         3.49 |          6.1 |          0.0010 |
|      25 |         500 |       00:02:01 |         2.67 |          3.6 |          0.0010 |
|      28 |         550 |       00:02:14 |         3.31 |          5.5 |          0.0010 |
|      30 |         600 |       00:02:25 |         2.49 |          3.1 |          0.0010 |
|      33 |         650 |       00:02:37 |         3.14 |          4.9 |          0.0010 |
|      35 |         700 |       00:02:49 |         2.29 |          2.6 |          0.0010 |
|      38 |         750 |       00:03:01 |         2.96 |          4.4 |          0.0010 |
|      40 |         800 |       00:03:12 |         2.12 |          2.2 |          0.0010 |
|      43 |         850 |       00:03:23 |         2.81 |          4.0 |          0.0010 |
|      45 |         900 |       00:03:35 |         1.98 |          2.0 |          0.0010 |
|      48 |         950 |       00:03:46 |         2.71 |          3.7 |          0.0010 |
|      50 |        1000 |       00:03:57 |         1.89 |          1.8 |          0.0010 |
|      53 |        1050 |       00:04:09 |         2.62 |          3.4 |          0.0010 |
|      55 |        1100 |       00:04:20 |         1.81 |          1.6 |          0.0010 |
|      58 |        1150 |       00:04:31 |         2.54 |          3.2 |          0.0010 |
|      60 |        1200 |       00:04:42 |         1.74 |          1.5 |          0.0010 |
|      63 |        1250 |       00:04:53 |         2.47 |          3.0 |          0.0010 |
|      65 |        1300 |       00:05:04 |         1.66 |          1.4 |          0.0010 |
|      68 |        1350 |       00:05:15 |         2.38 |          2.8 |          0.0010 |
|      70 |        1400 |       00:05:26 |         1.53 |          1.2 |          0.0010 |
|      73 |        1450 |       00:05:37 |         2.28 |          2.6 |          0.0010 |
|      75 |        1500 |       00:05:48 |         1.44 |          1.0 |          0.0010 |
|      78 |        1550 |       00:05:59 |         2.20 |          2.4 |          0.0010 |
|      80 |        1600 |       00:06:11 |         1.36 |          0.9 |          0.0010 |
|      83 |        1650 |       00:06:23 |         2.14 |          2.3 |          0.0010 |
|      85 |        1700 |       00:06:36 |         1.29 |          0.8 |          0.0010 |
|      88 |        1750 |       00:06:48 |         2.07 |          2.1 |          0.0010 |
|      90 |        1800 |       00:07:01 |         1.22 |          0.8 |          0.0010 |
|      93 |        1850 |       00:07:14 |         2.01 |          2.0 |          0.0010 |
|      95 |        1900 |       00:07:27 |         1.16 |          0.7 |          0.0010 |
|      98 |        1950 |       00:07:40 |         1.95 |          1.9 |          0.0010 |
|     100 |        2000 |       00:07:53 |         1.10 |          0.6 |          0.0010 |
|     103 |        2050 |       00:08:07 |         1.90 |          1.8 |          0.0010 |
|     105 |        2100 |       00:08:19 |         1.05 |          0.5 |          0.0010 |
|     108 |        2150 |       00:08:33 |         1.86 |          1.7 |          0.0010 |
|     110 |        2200 |       00:08:46 |         1.00 |          0.5 |          0.0010 |
|     113 |        2250 |       00:08:59 |         1.82 |          1.6 |          0.0010 |
|     115 |        2300 |       00:09:12 |         0.96 |          0.5 |          0.0010 |
|     118 |        2350 |       00:09:26 |         1.78 |          1.6 |          0.0010 |
|     120 |        2400 |       00:09:39 |         0.91 |          0.4 |          0.0010 |
|     123 |        2450 |       00:09:53 |         1.74 |          1.5 |          0.0010 |
|     125 |        2500 |       00:10:07 |         0.88 |          0.4 |          0.0010 |
|     128 |        2550 |       00:10:20 |         1.71 |          1.5 |          0.0010 |
|     130 |        2600 |       00:10:33 |         0.84 |          0.4 |          0.0010 |
|     133 |        2650 |       00:10:47 |         1.68 |          1.4 |          0.0010 |
|     135 |        2700 |       00:11:00 |         0.81 |          0.3 |          0.0010 |
|     138 |        2750 |       00:11:13 |         1.65 |          1.4 |          0.0010 |
|     140 |        2800 |       00:11:26 |         0.78 |          0.3 |          0.0010 |
|     143 |        2850 |       00:11:39 |         1.62 |          1.3 |          0.0010 |
|     145 |        2900 |       00:11:54 |         0.76 |          0.3 |          0.0010 |
|     148 |        2950 |       00:12:07 |         1.59 |          1.3 |          0.0010 |
|     150 |        3000 |       00:12:20 |         0.73 |          0.3 |          0.0010 |
|     153 |        3050 |       00:12:34 |         1.57 |          1.2 |          0.0010 |
|     155 |        3100 |       00:12:47 |         0.71 |          0.3 |          0.0010 |
|     158 |        3150 |       00:13:01 |         1.55 |          1.2 |          0.0010 |
|     160 |        3200 |       00:13:14 |         0.68 |          0.2 |          0.0010 |
|     163 |        3250 |       00:13:27 |         1.52 |          1.2 |          0.0010 |
|     165 |        3300 |       00:13:40 |         0.66 |          0.2 |          0.0010 |
|     168 |        3350 |       00:13:53 |         1.50 |          1.1 |          0.0010 |
|     170 |        3400 |       00:14:06 |         0.64 |          0.2 |          0.0010 |
|     173 |        3450 |       00:14:19 |         1.48 |          1.1 |          0.0010 |
|     175 |        3500 |       00:14:33 |         0.62 |          0.2 |          0.0010 |
|     178 |        3550 |       00:14:46 |         1.46 |          1.1 |          0.0010 |
|     180 |        3600 |       00:14:59 |         0.60 |          0.2 |          0.0010 |
|     183 |        3650 |       00:15:12 |         1.44 |          1.0 |          0.0010 |
|     185 |        3700 |       00:15:25 |         0.59 |          0.2 |          0.0010 |
|     188 |        3750 |       00:15:38 |         1.42 |          1.0 |          0.0010 |
|     190 |        3800 |       00:15:51 |         0.57 |          0.2 |          0.0010 |
|     193 |        3850 |       00:16:05 |         1.40 |          1.0 |          0.0010 |
|     195 |        3900 |       00:16:18 |         0.55 |          0.2 |          0.0010 |
|     198 |        3950 |       00:16:32 |         1.38 |          1.0 |          0.0010 |
|     200 |        4000 |       00:16:45 |         0.54 |          0.1 |          0.0010 |
|========================================================================================|
Training finished: 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)

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

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

% Predict output before maintenance and calculate error
yHatBefore = predict(net, XTestBefore);
errorBefore = helperCalculateError(XTestBefore, yHatBefore);

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

% Predict output after maintenance and calculate error
yHatAfter = predict(net, XTestAfter);
errorAfter = helperCalculateError(XTestAfter, yHatAfter);

helperVisualizeError(errorBefore, errorAfter);

異常の特定

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

XTestAll = helperExtractLabeledData(featureTest, "All");

yHatAll = predict(net, XTestAll);
errorAll = helperCalculateError(XTestAll, yHatAll);

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

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

helperVisualizeAnomalies(anomalies, errorAll, featureTest);

この例では、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

参考

| | |

関連するトピック