Anomaly Detection Sequence Prediction with LSTM

11 views (last 30 days)
Hi guys,
I built a LSTM network for an anomaly detection problem in which I had a pump system with more than 50 sensors and a categorical variable which returned the state of the system (NORMAL or RECOVERING). I reduced the number of sensors to have a leaner network and I trained it and classified the data.
Now, my teacher asked me to use the same dataset but for every observation I will have to use it to predict the label of the next observation and then return an error between the prediciton and the observed value. He said that the only difference with the previous problem is that now I have to remove the first observation of the categorical variable and the last observation of the sensors' set, in this way I can shift upward by one observation the categorical variable. At the end, I should have in the first observation the measures for the sensors of the first original observation and the label of the state of the system belonging to second observation in the original dataset. From this point, I think I should only run the network and the problem should be done.
I will attach the code that I wrote, but I don't understand if it is correct or if I should use something like predictAndUpdateState or classifyAndUpdateState functions for the test set.
Let me know and thanks for your help.
data = readtable('sensor.csv');
% Remove sensors which have a high number of 0s or NaNs (from 10000 up)
data(:,{'Var1','sensor_00','sensor_05','sensor_06','sensor_07','sensor_08','sensor_09','sensor_11','sensor_12','sensor_13','sensor_17','sensor_18','sensor_19','sensor_22','sensor_24','sensor_25','sensor_37','sensor_15','sensor_50','sensor_51'}) = [];
% Remove all the rows with BROKEN label (7 of 220320)
data(ismember(data.machine_status,'BROKEN'),:) = [];
S = data;
% Drop timestamp and machine_status to have only sensor variables
S(:,{'timestamp'}) = [];
% Rank features sequentially using the MRMR Algorithm
idx = fscmrmr(S,'machine_status');
% Keep only the first 15 out of 33 features (manually)
S(:,{'sensor_02','sensor_04','sensor_10','sensor_16','sensor_20','sensor_21','sensor_26','sensor_27','sensor_29','sensor_30','sensor_32','sensor_33','sensor_35','sensor_38','sensor_42','sensor_45','sensor_46','sensor_49','machine_status'}) = [];
% Normalize data using z-score method
S = normalize(S,'zscore');
% Transform sensors table into an array
Sensors = table2array(S);
% Interpolate all NaNs in each sensor
nanSensors = isnan(Sensors);
t = 1:numel(Sensors);
Sensors(nanSensors) = interp1(t(~nanSensors), Sensors(~nanSensors), t(nanSensors));
% Create a categorical array containing only the targets
MachineStatus = categorical(data.machine_status);
% Divide dataset in training set and test set (60% training and 40% test)
PD = 0.60;
SensorsTrain = Sensors(1:round(PD*length(MachineStatus))-1,:);
MachineStatusTrain = MachineStatus(2:round(PD*length(MachineStatus)));
SensorsTest = Sensors(round(PD*length(MachineStatus)):end-1,:);
MachineStatusTest = MachineStatus(round(PD*length(MachineStatus))+1:end);
% Transform sensors array in a cell array with each cell of dimension 1x15
% (one observation and 15 features)
SensorsTrain = num2cell(SensorsTrain,2);
SensorsTest = num2cell(SensorsTest,2);
% Transpose each cell to have the features as rows
SensorsTrain = cellfun(@transpose,SensorsTrain,'UniformOutput',false);
SensorsTest = cellfun(@transpose,SensorsTest,'UniformOutput',false);
% LSTM Neural Network (15 features and two classes, NORMAL and RECOVERING)
numFeatures = 15
numHiddenUnits = 100
numClasses = 2
layers = [ ...
sequenceInputLayer(numFeatures)
lstmLayer(numHiddenUnits,'OutputMode','last')
fullyConnectedLayer(numClasses)
softmaxLayer
classificationLayer
]
options = trainingOptions('adam', ...
'MaxEpochs',20, ...
'MiniBatchSize', 13218, ...
'InitialLearnRate', 0.001, ...
'GradientThreshold', 1, ...
'ExecutionEnvironment',"cpu",...
'plots','training-progress', ...
'Verbose',false);
net = trainNetwork(SensorsTrain,MachineStatusTrain,layers,options);
% Visualize the Training and Testing Accuracy using confusion matrices
trainPred = classify(net,SensorsTrain);
LSTMAccuracy = sum(trainPred == MachineStatusTrain)/numel(MachineStatusTrain)*100
figure
ccLSTM = confusionchart(MachineStatusTrain,trainPred);
ccLSTM.Title = 'Confusion Chart for LSTM';
ccLSTM.ColumnSummary = 'column-normalized';
ccLSTM.RowSummary = 'row-normalized';
testPred = classify(net,SensorsTest);
LSTMAccuracy = sum(testPred == MachineStatusTest)/numel(MachineStatusTest)*100
figure
ccLSTM = confusionchart(MachineStatusTest,testPred);
ccLSTM.Title = 'Confusion Chart for LSTM';
ccLSTM.ColumnSummary = 'column-normalized';
ccLSTM.RowSummary = 'row-normalized';

Answers (1)

Musa Muhammad
Musa Muhammad on 31 Mar 2020
From what i understood, your teacher wants you to use predictive model rather than the classification. The easiest way to do it is using the GUI neural network time series and load your data, configure the delay and hidden layer parameters. Is pretty straight forward and easy to use.

Categories

Find more on Sequence and Numeric Feature Data Workflows in Help Center and File Exchange

Products

Community Treasure Hunt

Find the treasures in MATLAB Central and discover how the community can help you!

Start Hunting!