|
| 1 | +%% CoolingFanAnomalyDetectionExample |
| 2 | +% This is the original example simulation that has been copied and modified to |
| 3 | +% support batch constraints inside simulation.m. The current file serves as a reference |
| 4 | +% for the original implementation before the modifications were made to handle |
| 5 | +% batch processing constraints. |
| 6 | + |
| 7 | +addpath('Data_Generator/', 'Data_Generator/VaryingConvectionLib/'); |
| 8 | +mdl = "CoolingFanWithFaults"; |
| 9 | +open_system(mdl) |
| 10 | + |
| 11 | +generateFlag = false; |
| 12 | +if isfolder('./Data') |
| 13 | + folderContent = dir('Data/CoolingFan*.mat'); |
| 14 | + if isempty(folderContent) |
| 15 | + generateFlag = true; |
| 16 | + else |
| 17 | + numSim = numel(folderContent); |
| 18 | + end |
| 19 | +else |
| 20 | + generateFlag = true; |
| 21 | +end |
| 22 | + |
| 23 | +if generateFlag |
| 24 | + numSim = 5; |
| 25 | + rng("default"); |
| 26 | + generateData('training', numSim); |
| 27 | +end |
| 28 | + |
| 29 | +ensemble = simulationEnsembleDatastore(pwd,'simulation','Data'); |
| 30 | +ensemble.SelectedVariables = ["Signals", "Anomalies"]; |
| 31 | + |
| 32 | +trainEnsemble = subset(ensemble, 1:numSim-3); |
| 33 | +testEnsemble = subset(ensemble, numSim-2:numSim-1); |
| 34 | +validationEnsemble = subset(ensemble, numSim); |
| 35 | + |
| 36 | +tempData = trainEnsemble.read; |
| 37 | +signal_data = tempData.Signals{1}; |
| 38 | +anomaly_data = tempData.Anomalies{1}; |
| 39 | + |
| 40 | +h = figure; |
| 41 | +tiledlayout("vertical"); |
| 42 | +ax1 = nexttile; plot(signal_data.Data(:,1)); |
| 43 | +ax2 = nexttile; plot(signal_data.Data(:,2)); |
| 44 | +ax3 = nexttile; plot(signal_data.Data(:,3)); |
| 45 | +ax4 = nexttile; plot(anomaly_data.Data(:,1), 'bx', 'MarkerIndices',find(anomaly_data.Data(:,1)>0.1), 'MarkerSize', 5); hold on; |
| 46 | +plot(anomaly_data.Data(:,2), 'ro', 'MarkerIndices',find(anomaly_data.Data(:,2)>0.1), 'MarkerSize', 5); |
| 47 | +plot(anomaly_data.Data(:,3), 'square', 'Color', 'g', 'MarkerIndices',find(anomaly_data.Data(:,3)>0.1), 'MarkerSize', 5); |
| 48 | +linkaxes([ax1 ax2 ax3 ax4],'x') |
| 49 | +ylim([0, 2]); |
| 50 | +legend("Load Anomaly", "Fan Anomaly", "Power Supply Anomaly", 'Location', 'bestoutside') |
| 51 | +set(h,'Units','normalized','Position',[0 0 1 .8]); |
| 52 | + |
| 53 | +trainingData = trainEnsemble.readall; |
| 54 | +anomaly_data = vertcat(trainingData.Anomalies{:}); |
| 55 | +labelArray={'Normal','Anomaly1','Anomaly2', 'Anomaly3', 'Anomaly12','Anomaly13','Anomaly23','Anomaly123'}'; |
| 56 | +yCategoricalTrain=labelArray(sum(anomaly_data.Data.*2.^(size(anomaly_data.Data,2)-1:-1:0),2)+1,1); |
| 57 | +yCategoricalTrain=categorical(yCategoricalTrain); |
| 58 | +summary(yCategoricalTrain); |
| 59 | + |
| 60 | +yTrainAnomaly1=logical(anomaly_data.Data(:,1)); |
| 61 | +yTrainAnomaly2=logical(anomaly_data.Data(:,2)); |
| 62 | +yTrainAnomaly3=logical(anomaly_data.Data(:,3)); |
| 63 | + |
| 64 | +windowSize=2000; |
| 65 | +sensorDataTrain = vertcat(trainingData.Signals{:}); |
| 66 | +ensembleTableTrain1 = generateEnsembleTable(sensorDataTrain.Data,yTrainAnomaly1,windowSize); |
| 67 | +ensembleTableTrain2 = generateEnsembleTable(sensorDataTrain.Data,yTrainAnomaly2,windowSize); |
| 68 | +ensembleTableTrain3 = generateEnsembleTable(sensorDataTrain.Data,yTrainAnomaly3,windowSize); |
| 69 | + |
| 70 | +ensembleTableTrain1_reduced = downsampleNormalData(ensembleTableTrain1); |
| 71 | +ensembleTableTrain2_reduced = downsampleNormalData(ensembleTableTrain2); |
| 72 | +ensembleTableTrain3_reduced = downsampleNormalData(ensembleTableTrain3); |
| 73 | + |
| 74 | +startApp = false; |
| 75 | +if startApp |
| 76 | + diagnosticFeatureDesigner; %#ok<UNRCH> |
| 77 | +end |
| 78 | + |
| 79 | +featureTableTrain1 = diagnosticFeatures(ensembleTableTrain1_reduced); |
| 80 | +featureTableTrain2 = diagnosticFeatures(ensembleTableTrain2_reduced); |
| 81 | +featureTableTrain3 = diagnosticFeatures(ensembleTableTrain3_reduced); |
| 82 | + |
| 83 | +head(featureTableTrain1); |
| 84 | + |
| 85 | +m.m1 = fitcsvm(featureTableTrain1, 'Anomaly', 'Standardize',true, 'KernelFunction','gaussian'); |
| 86 | +m.m2 = fitcsvm(featureTableTrain2, 'Anomaly', 'Standardize',true, 'KernelFunction','gaussian'); |
| 87 | +m.m3 = fitcsvm(featureTableTrain3, 'Anomaly', 'Standardize',true, 'KernelFunction','gaussian'); |
| 88 | + |
| 89 | +save anomalyDetectionModelSVM m |
| 90 | + |
| 91 | +testData = testEnsemble.readall; |
| 92 | +anomaly_data_test = vertcat(testData.Anomalies{:}); |
| 93 | + |
| 94 | +yTestAnomaly1=logical(anomaly_data_test.Data(:,1)); |
| 95 | +yTestAnomaly2=logical(anomaly_data_test.Data(:,2)); |
| 96 | +yTestAnomaly3=logical(anomaly_data_test.Data(:,3)); |
| 97 | + |
| 98 | +sensorDataTest = vertcat(testData.Signals{:}); |
| 99 | +ensembleTableTest1 = generateEnsembleTable(sensorDataTest.Data,yTestAnomaly1,windowSize); |
| 100 | +ensembleTableTest2 = generateEnsembleTable(sensorDataTest.Data,yTestAnomaly2,windowSize); |
| 101 | +ensembleTableTest3 = generateEnsembleTable(sensorDataTest.Data,yTestAnomaly3,windowSize); |
| 102 | + |
| 103 | +featureTableTest1 = diagnosticFeatures(ensembleTableTest1); |
| 104 | +featureTableTest2 = diagnosticFeatures(ensembleTableTest2); |
| 105 | +featureTableTest3 = diagnosticFeatures(ensembleTableTest3); |
| 106 | + |
| 107 | +results1 = m.m1.predict(featureTableTest1(:, 2:end)); |
| 108 | +results2 = m.m2.predict(featureTableTest2(:, 2:end)); |
| 109 | +results3 = m.m3.predict(featureTableTest3(:, 2:end)); |
| 110 | + |
| 111 | +yT = [featureTableTest1.Anomaly, featureTableTest2.Anomaly, featureTableTest3.Anomaly]; |
| 112 | +yCategoricalT = labelArray(sum(yT.*2.^(size(yT,2)-1:-1:0),2)+1,1); |
| 113 | +yCategoricalT = categorical(yCategoricalT); |
| 114 | + |
| 115 | +yHat = [results1, results2, results3]; |
| 116 | +yCategoricalTestHat=labelArray(sum(yHat.*2.^(size(yHat,2)-1:-1:0),2)+1,1); |
| 117 | +yCategoricalTestHat=categorical(yCategoricalTestHat); |
| 118 | + |
| 119 | +figure |
| 120 | +confusionchart(yCategoricalT, yCategoricalTestHat) |
| 121 | + |
| 122 | +figure |
| 123 | +tiledlayout(1,3); |
| 124 | +nexttile; confusionchart(featureTableTest1.Anomaly, results1); |
| 125 | +nexttile; confusionchart(featureTableTest2.Anomaly, results2); |
| 126 | +nexttile; confusionchart(featureTableTest3.Anomaly, results3); |
0 commit comments