Main Content

Human Activity Recognition Using Mobile Phone Data

This example shows how to extract features for human activity based smartphone sensor signals that can be used for classifying human activity using the classificationLearner app. The feature extraction for the data is done using the signalTimeFeatureExtractor and signalFrequencyFeatureExtractor which provide convenient and performant APIs. The classificationLearner app is used for analyzing and creating classification model.

Load Sample Data Set

Load the BufferedHumanactivity data set.

load BufferedHumanactivity

The BufferedHumanactivity data set contains 7776 observations of 4 different physical human activities: Sitting, Standing, Walking and Running. Each observation has a length of 44 samples and associated with one activity. The data set contains the following variables:

  • [atx, aty, atz] — Buffered accelerometer sensor data of fixed length

  • actid — Response vector containing the activity IDs in integers: 1, 2, 3, and 4 representing Sitting, Standing, Walking and Running respectively

  • actnames — Name of activity corresponding to activity ID

  • fs — Sample rate of accelerometer sensor data

The Sensor HAR (human activity recognition) App [1] was used to collect raw accelerometer signals in [2] which is used to build the BufferedHumanactivity data set. The smartphone is worn by a subject during five different types of physical activity. The data set in [2] was then buffered where each line corresponds to an observation signal of 44 samples corresponding to one activity. The Dancing activity from the data set in [2] was excluded when exporting data to BufferedHumanactivity.

Feature extraction

There are two main different types of causes behind our signals:

  • One to do with "fast" variations over time, due to body dynamics (physical movements of the subject)

  • The other, responsible for "slow" variations over time, due to the position of the body with respect to the vertical gravitational field

To isolate the rapid signal variations from the slower ones we will apply high pass filter to the original signal. Then different features are extracted from filtered and unfiltered data for human activities classification which is done using the signalTimeFeatureExtractor and signalFrequencyFeatureExtractor.

atx = atx.';
aty = aty.';
atz = atz.';
% Initialize digital filter
fhp = accHighPassfilter; 
% use high pass
atxFiltered =  filter(fhp,atx);
atyFiltered =  filter(fhp,aty);
atzFiltered =  filter(fhp,atz);

For time features, signalTimeFeatureExtractor is used to extract the mean of the unfiltered signal and the RMS, ShapeFactor, PeakValue, CrestFactor, ClearanceFactor and ImpulseFactor of the filtered signal. Hence two signalTimeFeatureExtractor objects meanFE and timeFE are configured as shown below.

meanFE = signalTimeFeatureExtractor("Mean",true,"SampleRate",fs);
timeFE = signalTimeFeatureExtractor("RMS",true,...
    "ShapeFactor",true,...
    "PeakValue",true,...
    "CrestFactor",true,...
    "ClearanceFactor",true,...    
    "ImpulseFactor",true,...
    "SampleRate",fs);

For frequency features, signalFrequencyFeatureExtractor is used to extract the MeanFrequency, BandPower, PowerBandwidth, PeakAmplitude and PeakLocation of the filtered signal. Hence a signalFrequencyFeatureExtractor object freqFE is configured as shown below.

freqFE = signalFrequencyFeatureExtractor("PeakAmplitude",true,...
    "PeakLocation",true,...
    "MeanFrequency",true,...
    "BandPower",true,...
    "PowerBandwidth",true,...
    "SampleRate",fs);

The computation of PeakAmplitude and PeakLocation of welch's PSD can be refined by adding more specific requirements. Here we will find a maximum of 6 peaks, at least 0.25Hz apart from each other. Additionally, the welch's PSD computation is done using fftLength of 256 and rectangular window of same size as the input signal.

fftLength = 256;
window = rectwin(size(atx,1));
setExtractorParameters(freqFE,"WelchPSD","FFTLength",fftLength,"Window",window);
mindist_xunits = 0.25;
minpkdist = floor(mindist_xunits/(fs/fftLength));
setExtractorParameters(freqFE,"PeakAmplitude","MaxNumExtrema",6,"MinSeparation",minpkdist);
setExtractorParameters(freqFE,"PeakLocation","MaxNumExtrema",6,"MinSeparation",minpkdist);

Computation of features for all signals is done using the signalDatastore and feature extractor object. The signalDatastore is used for accessing in-memory buffered data atx, aty, atz, atxFiltered, atyFiltered and atzFiltered and its transform method is passed a handle to extract method of feature extractor object as shown below.

meanFeatureDs = signalDatastore({atx,aty,atz});
meanFeatureDs = transform(meanFeatureDs,@meanFE.extract);
timeFeatureDs = signalDatastore({atxFiltered,atyFiltered,atzFiltered});
timeFeatureDs = transform(timeFeatureDs,@timeFE.extract);
freqFeatureDs = signalDatastore({atxFiltered,atyFiltered,atzFiltered});
freqFeatureDs = transform(freqFeatureDs,@freqFE.extract);

To compute features for all signals the readall method of transformed datastore is called using "UseParallel" flag which distributes the computations to a pool of workers if Parallel Computing Toolbox is installed. Finally all computed features as combined and reshaped into rawFeatures and normalized using mean and standard deviation of the rawFeatures.

meanFeatures = readall(meanFeatureDs,"UseParallel",true);
timeFeatures = readall(timeFeatureDs,"UseParallel",true);
freqFeatures =  readall(freqFeatureDs,"UseParallel",true);
% We will have 66 feature columns for each 7776 observations
rawFeatures  = reshape([meanFeatures,timeFeatures,freqFeatures],66,size(atx,2)).';
fmean = mean(rawFeatures,1);
fstd = std(rawFeatures,[],1);
features = rawFeatures-fmean;
features = features./fstd;

Train a Support Vector Machine (SVM) classifier

For classification, import the data into classification learner app and train a SVM classifier. Alternatively, use the MATLAB function trainClassifier that was auto generated by the classification learner app to train a classifier based on the data set. The returned arguments include information of how the data set was partition during the training phase - so the remaining samples of the data set can be used for testing the accuracy of the classifier.

featurelabels = getFeatureNames();
FeatureTable = array2table(features,'VariableNames',featurelabels);
actioncats = categorical(actnames)';
FeatureTable.ActivityID = actioncats(actid);
[trainedClassifier, accuracy, cvp] = trainClassifier(FeatureTable);

PredictedAction = trainedClassifier.predictFcn(FeatureTable(cvp.test, 1:width(FeatureTable)-1));
TrueAction = FeatureTable.ActivityID(cvp.test);

figure
heatmap(table(PredictedAction, TrueAction), 'PredictedAction', 'TrueAction');

Summary

In this example, you saw how extract features for human activity based smartphone sensor signals using signalTimeFeatureExtractor and signalFrequencyFeatureExtractor .You saw how to use the extracted feature to train a SVM model using the Classification Learner App which resulted in about 95% accuracy. As an alternative approach, we can also explore using deep networks with the featureInput layer to classify the human activity.

References

[1] El Helou, A. Sensor HAR recognition App. MathWorks File Exchange https://www.mathworks.com/matlabcentral/fileexchange/54138-sensor-har-recognition-app

[2] El Helou, A. Sensor Data Analytics. MathWorks File Exchange https://www.mathworks.com/matlabcentral/fileexchange/54139-sensor-data-analytics--french-webinar-code-

Supporting Functions

hpfilter Function:

A function which returns a filter object with desired specification.

function designedFilter = accHighPassfilter
Fs = 10;  % Sampling Frequency
Fstop = 0.4;         % Stopband Frequency
Fpass = 0.8;         % Passband Frequency
Astop = 60;          % Stopband Attenuation (dB)
Apass = 0.1;         % Passband Ripple (dB)
match = 'passband';  % Band to match exactly

designedFilter = designfilt('highpassiir', ...
    'StopbandFrequency',Fstop,'PassbandFrequency',Fpass, ...
    'StopbandAttenuation',Astop,'PassbandRipple',Apass, ...
    'SampleRate',Fs,'DesignMethod','ellip',...
    'MatchExactly',match);
end

trainClassifier Function:

A function generated from classification learner app which returns a trained classifier and its accuracy. Additionally the data partition variable cvp was added as output parameter to test the trained model.

function [trainedClassifier, validationAccuracy,cvp] = trainClassifier(trainingData)
% [trainedClassifier, validationAccuracy] = trainClassifier(trainingData)
% Returns a trained classifier and its accuracy. This code recreates the
% classification model trained in Classification Learner app. Use the
% generated code to automate training the same model with new data, or to
% learn how to programmatically train models.
%
%  Input:
%      trainingData: A table containing the same predictor and response
%       columns as those imported into the app.
%
%  Output:
%      trainedClassifier: A struct containing the trained classifier. The
%       struct contains various fields with information about the trained
%       classifier.
%
%      trainedClassifier.predictFcn: A function to make predictions on new
%       data.
%
%      validationAccuracy: A double containing the accuracy in percent. In
%       the app, the History list displays this overall accuracy score for
%       each model.
%
% Use the code to train the model with new data. To retrain your
% classifier, call the function from the command line with your original
% data or new data as the input argument trainingData.
%
% For example, to retrain a classifier trained with the original data set
% T, enter:
%   [trainedClassifier, validationAccuracy] = trainClassifier(T)
%
% To make predictions with the returned 'trainedClassifier' on new data T2,
% use
%   yfit = trainedClassifier.predictFcn(T2)
%
% T2 must be a table containing at least the same predictor columns as used
% during training. For details, enter:
%   trainedClassifier.HowToPredict

% Auto-generated by MATLAB on 01-Jun-2021 11:34:54


% Extract predictors and response
% This code processes the data into the right shape for training the
% model.
inputTable = trainingData;
predictorNames = {'TotalAccXMean', 'TotalAccYMean', 'TotalAccZMean', 'BodyAccXRMS', 'BodyAccYRMS', 'BodyAccZRMS', 'BodyAccXShapeFactor', 'BodyAccYShapeFactor', 'BodyAccZShapeFactor', 'BodyAccXPeakValue', 'BodyAccYPeakValue', 'BodyAccZPeakValue', 'BodyAccXCrestFactor', 'BodyAccYCrestFactor', 'BodyAccZCrestFactor', 'BodyAccXClearanceFactor', 'BodyAccYClearanceFactor', 'BodyAccZClearanceFactor', 'BodyAccXImpulseFactor', 'BodyAccYImpulseFactor', 'BodyAccZImpulseFactor', 'BodyAccXMeanFrequency', 'BodyAccYMeanFrequency', 'BodyAccZMeanFrequency', 'BodyAccXBandPower', 'BodyAccYBandPower', 'BodyAccZBandPower', 'BodyAccXPowerBandwidth', 'BodyAccYPowerBandwidth', 'BodyAccZPowerBandwidth', 'BodyAccXSpectVal1', 'BodyAccXSpectVal2', 'BodyAccXSpectVal3', 'BodyAccXSpectVal4', 'BodyAccXSpectVal5', 'BodyAccXSpectVal6', 'BodyAccXSpectPos1', 'BodyAccXSpectPos2', 'BodyAccXSpectPos3', 'BodyAccXSpectPos4', 'BodyAccXSpectPos5', 'BodyAccXSpectPos6', 'BodyAccYSpectVal1', 'BodyAccYSpectVal2', 'BodyAccYSpectVal3', 'BodyAccYSpectVal4', 'BodyAccYSpectVal5', 'BodyAccYSpectVal6', 'BodyAccYSpectPos1', 'BodyAccYSpectPos2', 'BodyAccYSpectPos3', 'BodyAccYSpectPos4', 'BodyAccYSpectPos5', 'BodyAccYSpectPos6', 'BodyAccZSpectVal1', 'BodyAccZSpectVal2', 'BodyAccZSpectVal3', 'BodyAccZSpectVal4', 'BodyAccZSpectVal5', 'BodyAccZSpectVal6', 'BodyAccZSpectPos1', 'BodyAccZSpectPos2', 'BodyAccZSpectPos3', 'BodyAccZSpectPos4', 'BodyAccZSpectPos5', 'BodyAccZSpectPos6'};
predictors = inputTable(:, predictorNames);
response = inputTable.ActivityID;
isCategoricalPredictor = [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false]; %#ok<NASGU> 

% Train a classifier
% This code specifies all the classifier options and trains the classifier.
template = templateSVM(...
    'KernelFunction', 'polynomial', ...
    'PolynomialOrder', 2, ...
    'KernelScale', 'auto', ...
    'BoxConstraint', 1, ...
    'Standardize', true);
classificationSVM = fitcecoc(...
    predictors, ...
    response, ...
    'Learners', template, ...
    'Coding', 'onevsone', ...
    'ClassNames', categorical({'Running'; 'Sitting'; 'Standing'; 'Walking'}));

% Create the result struct with predict function
predictorExtractionFcn = @(t) t(:, predictorNames);
svmPredictFcn = @(x) predict(classificationSVM, x);
trainedClassifier.predictFcn = @(x) svmPredictFcn(predictorExtractionFcn(x));

% Add additional fields to the result struct
trainedClassifier.RequiredVariables = {'BodyAccXBandPower', 'BodyAccXClearanceFactor', 'BodyAccXCrestFactor', 'BodyAccXImpulseFactor', 'BodyAccXMeanFrequency', 'BodyAccXPeakValue', 'BodyAccXPowerBandwidth', 'BodyAccXRMS', 'BodyAccXShapeFactor', 'BodyAccXSpectPos1', 'BodyAccXSpectPos2', 'BodyAccXSpectPos3', 'BodyAccXSpectPos4', 'BodyAccXSpectPos5', 'BodyAccXSpectPos6', 'BodyAccXSpectVal1', 'BodyAccXSpectVal2', 'BodyAccXSpectVal3', 'BodyAccXSpectVal4', 'BodyAccXSpectVal5', 'BodyAccXSpectVal6', 'BodyAccYBandPower', 'BodyAccYClearanceFactor', 'BodyAccYCrestFactor', 'BodyAccYImpulseFactor', 'BodyAccYMeanFrequency', 'BodyAccYPeakValue', 'BodyAccYPowerBandwidth', 'BodyAccYRMS', 'BodyAccYShapeFactor', 'BodyAccYSpectPos1', 'BodyAccYSpectPos2', 'BodyAccYSpectPos3', 'BodyAccYSpectPos4', 'BodyAccYSpectPos5', 'BodyAccYSpectPos6', 'BodyAccYSpectVal1', 'BodyAccYSpectVal2', 'BodyAccYSpectVal3', 'BodyAccYSpectVal4', 'BodyAccYSpectVal5', 'BodyAccYSpectVal6', 'BodyAccZBandPower', 'BodyAccZClearanceFactor', 'BodyAccZCrestFactor', 'BodyAccZImpulseFactor', 'BodyAccZMeanFrequency', 'BodyAccZPeakValue', 'BodyAccZPowerBandwidth', 'BodyAccZRMS', 'BodyAccZShapeFactor', 'BodyAccZSpectPos1', 'BodyAccZSpectPos2', 'BodyAccZSpectPos3', 'BodyAccZSpectPos4', 'BodyAccZSpectPos5', 'BodyAccZSpectPos6', 'BodyAccZSpectVal1', 'BodyAccZSpectVal2', 'BodyAccZSpectVal3', 'BodyAccZSpectVal4', 'BodyAccZSpectVal5', 'BodyAccZSpectVal6', 'TotalAccXMean', 'TotalAccYMean', 'TotalAccZMean'};
trainedClassifier.ClassificationSVM = classificationSVM;
trainedClassifier.About = 'This struct is a trained model exported from Classification Learner R2021b.';
trainedClassifier.HowToPredict = sprintf('To make predictions on a new table, T, use: \n  yfit = c.predictFcn(T) \nreplacing ''c'' with the name of the variable that is this struct, e.g. ''trainedModel''. \n \nThe table, T, must contain the variables returned by: \n  c.RequiredVariables \nVariable formats (e.g. matrix/vector, datatype) must match the original training data. \nAdditional variables are ignored. \n \nFor more information, see <a href="matlab:helpview(fullfile(docroot, ''stats'', ''stats.map''), ''appclassification_exportmodeltoworkspace'')">How to predict using an exported model</a>.');

% Extract predictors and response
% This code processes the data into the right shape for training the
% model.
inputTable = trainingData;
predictorNames = {'TotalAccXMean', 'TotalAccYMean', 'TotalAccZMean', 'BodyAccXRMS', 'BodyAccYRMS', 'BodyAccZRMS', 'BodyAccXShapeFactor', 'BodyAccYShapeFactor', 'BodyAccZShapeFactor', 'BodyAccXPeakValue', 'BodyAccYPeakValue', 'BodyAccZPeakValue', 'BodyAccXCrestFactor', 'BodyAccYCrestFactor', 'BodyAccZCrestFactor', 'BodyAccXClearanceFactor', 'BodyAccYClearanceFactor', 'BodyAccZClearanceFactor', 'BodyAccXImpulseFactor', 'BodyAccYImpulseFactor', 'BodyAccZImpulseFactor', 'BodyAccXMeanFrequency', 'BodyAccYMeanFrequency', 'BodyAccZMeanFrequency', 'BodyAccXBandPower', 'BodyAccYBandPower', 'BodyAccZBandPower', 'BodyAccXPowerBandwidth', 'BodyAccYPowerBandwidth', 'BodyAccZPowerBandwidth', 'BodyAccXSpectVal1', 'BodyAccXSpectVal2', 'BodyAccXSpectVal3', 'BodyAccXSpectVal4', 'BodyAccXSpectVal5', 'BodyAccXSpectVal6', 'BodyAccXSpectPos1', 'BodyAccXSpectPos2', 'BodyAccXSpectPos3', 'BodyAccXSpectPos4', 'BodyAccXSpectPos5', 'BodyAccXSpectPos6', 'BodyAccYSpectVal1', 'BodyAccYSpectVal2', 'BodyAccYSpectVal3', 'BodyAccYSpectVal4', 'BodyAccYSpectVal5', 'BodyAccYSpectVal6', 'BodyAccYSpectPos1', 'BodyAccYSpectPos2', 'BodyAccYSpectPos3', 'BodyAccYSpectPos4', 'BodyAccYSpectPos5', 'BodyAccYSpectPos6', 'BodyAccZSpectVal1', 'BodyAccZSpectVal2', 'BodyAccZSpectVal3', 'BodyAccZSpectVal4', 'BodyAccZSpectVal5', 'BodyAccZSpectVal6', 'BodyAccZSpectPos1', 'BodyAccZSpectPos2', 'BodyAccZSpectPos3', 'BodyAccZSpectPos4', 'BodyAccZSpectPos5', 'BodyAccZSpectPos6'};
predictors = inputTable(:, predictorNames);
response = inputTable.ActivityID;
isCategoricalPredictor = [false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false, false];

% Set up holdout validation
cvp = cvpartition(response, 'Holdout', 0.25);
trainingPredictors = predictors(cvp.training, :);
trainingResponse = response(cvp.training, :);
trainingIsCategoricalPredictor = isCategoricalPredictor; %#ok<NASGU> 

% Train a classifier
% This code specifies all the classifier options and trains the classifier.
template = templateSVM(...
    'KernelFunction', 'polynomial', ...
    'PolynomialOrder', 2, ...
    'KernelScale', 'auto', ...
    'BoxConstraint', 1, ...
    'Standardize', true);
classificationSVM = fitcecoc(...
    trainingPredictors, ...
    trainingResponse, ...
    'Learners', template, ...
    'Coding', 'onevsone', ...
    'ClassNames', categorical({'Running'; 'Sitting'; 'Standing'; 'Walking'}));

% Create the result struct with predict function
svmPredictFcn = @(x) predict(classificationSVM, x);
validationPredictFcn = @(x) svmPredictFcn(x);

% Add additional fields to the result struct


% Compute validation predictions
validationPredictors = predictors(cvp.test, :);
validationResponse = response(cvp.test, :);
[validationPredictions, ~] = validationPredictFcn(validationPredictors);

% Compute validation accuracy
correctPredictions = (validationPredictions == validationResponse);
isMissing = ismissing(validationResponse);
correctPredictions = correctPredictions(~isMissing);
validationAccuracy = sum(correctPredictions)/length(correctPredictions);
end

getFeatureNames Function:

The getFeatureNames function returns the names of all the individual features computed

function featureNames = getFeatureNames
% FEATURENAMES Return the names of all the individual features computed

idx = 1;
featureNames(idx,1) = {'TotalAccXMean'};
idx = idx+1;
featureNames(idx,1) = {'TotalAccYMean'};
idx = idx+1;
featureNames(idx,1) = {'TotalAccZMean'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccXRMS'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccYRMS'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccZRMS'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccXShapeFactor'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccYShapeFactor'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccZShapeFactor'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccXPeakValue'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccYPeakValue'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccZPeakValue'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccXCrestFactor'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccYCrestFactor'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccZCrestFactor'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccXClearanceFactor'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccYClearanceFactor'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccZClearanceFactor'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccXImpulseFactor'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccYImpulseFactor'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccZImpulseFactor'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccXMeanFrequency'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccYMeanFrequency'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccZMeanFrequency'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccXBandPower'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccYBandPower'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccZBandPower'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccXPowerBandwidth'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccYPowerBandwidth'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccZPowerBandwidth'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccXSpectVal1'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccXSpectVal2'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccXSpectVal3'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccXSpectVal4'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccXSpectVal5'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccXSpectVal6'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccXSpectPos1'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccXSpectPos2'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccXSpectPos3'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccXSpectPos4'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccXSpectPos5'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccXSpectPos6'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccYSpectVal1'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccYSpectVal2'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccYSpectVal3'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccYSpectVal4'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccYSpectVal5'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccYSpectVal6'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccYSpectPos1'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccYSpectPos2'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccYSpectPos3'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccYSpectPos4'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccYSpectPos5'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccYSpectPos6'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccZSpectVal1'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccZSpectVal2'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccZSpectVal3'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccZSpectVal4'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccZSpectVal5'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccZSpectVal6'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccZSpectPos1'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccZSpectPos2'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccZSpectPos3'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccZSpectPos4'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccZSpectPos5'};
idx = idx+1;
featureNames(idx,1) = {'BodyAccZSpectPos6'};
end

See Also

(Statistics and Machine Learning Toolbox) |