%% Use VGGish Embeddings for Machine Learning
% Download and unzip the air compressor data set [1]. This data set consists of recordings from air compressors in a healthy state or in one of seven faulty states.

url = 'https://www.mathworks.com/supportfiles/audio/AirCompressorDataset/AirCompressorDataset.zip';
downloadFolder = fullfile(tempdir,'aircompressordataset');
datasetLocation = tempdir;

if ~exist(fullfile(tempdir,'AirCompressorDataSet'),'dir')
    loc = websave(downloadFolder,url);
    unzip(loc,fullfile(tempdir,'AirCompressorDataSet'))
end

%
% Create an audioDatastore object to manage the data and split it into training and validation sets.

ads = audioDatastore(downloadFolder,'IncludeSubfolders',true,'LabelSource','foldernames');

%
% In this example, you classify signals as either healthy or faulty. Combine all of the faulty labels into a single label. Split the datastore into training and validation sets.

labels = ads.Labels;
labels(labels~=categorical("Healthy")) = categorical("Faulty");
ads.Labels = removecats(labels);

[adsTrain,adsValidation] = splitEachLabel(ads,0.8,0.2);

%
% Extract VGGish features from the training set. Each audio file corresponds to multiple VGGish features. Replicate the labels so that they are in one-to-one correspondence with the features.

trainFeatures = [];
trainLabels = [];
for idx = 1:numel(adsTrain.Files)
    [audioIn,fileInfo] = read(adsTrain);
    features = vggishFeatures(audioIn,fileInfo.SampleRate);
    trainFeatures = [trainFeatures;features];
    trainLabels = [trainLabels;repelem(fileInfo.Label,size(features,1))'];
end

%
% Train a cubic support vector machine (SVM) using fitcsvm. To explore other classifiers and their performances, use Classification Learner.

faultDetector = fitcsvm( ...
    trainFeatures, ...
    trainLabels, ...
    'KernelFunction','polynomial', ...
    'PolynomialOrder',3, ...
    'KernelScale','auto', ...
    'BoxConstraint',1, ...
    'Standardize',true, ...
    'ClassNames',categories(trainLabels));

%
% For each file in the validation set:
% Extract VGGish features.
% For each VGGish feature vector in a file, use the trained classifier to predict whether the machine is healthy or faulty.
% Take the mode of the predictions for each file.

predictions = [];
for idx = 1:numel(adsValidation.Files)
    [audioIn,fileInfo] = read(adsValidation);
    
    features = vggishFeatures(audioIn,fileInfo.SampleRate);
    
    predictionsPerFile = categorical(predict(faultDetector,features));
    
    predictions = [predictions;mode(predictionsPerFile)];
end

%
% Use confusionchart to display the performance of the classifier.

accuracy = sum(predictions==adsValidation.Labels)/numel(adsValidation.Labels);
cc = confusionchart(predictions,adsValidation.Labels);
cc.Title = sprintf('Accuracy = %0.2f %',accuracy*100);

%
%% References
% [1] Verma, Nishchal K., Rahul Kumar Sevakula, Sonal Dixit, and Al Salour. 2016. “Intelligent Condition Based Monitoring Using Acoustic Signals for Air Compressors.” IEEE Transactions on Reliability 65 (1): 291–309. https://doi.org/10.1109/TR.2015.2459684.
% Copyright 2020 The MathWorks, Inc.