function [trainedClassifier, validationAccuracy] = trainClassifier(trainingData)
% trainClassifier(trainingData)
%  returns a trained classifier and its accuracy.
%  This code recreates the classification model trained in
%  Classification Learner app.
%
%   Input:
%       trainingData: the training data of same data type as imported
%        in the app (table or matrix).
%
%   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. It takes an input of the same form as this training
%        code (table or matrix) and returns predictions for the response.
%        If you supply a matrix, include only the predictors columns (or
%        rows).
%
%       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 T,
%  use
%    yfit = trainedClassifier.predictFcn(T)
%
%  To automate training the same classifier with new data, or to learn how
%  to programmatically train classifiers, examine the generated code.

% Auto-generated by MATLAB on 24-May-2018 10:33:32


% Extract predictors and response
% This code processes the data into the right shape for training the
% classifier.
inputTable = trainingData;
% Split matrices in the input table into vectors
inputTable = [inputTable(:,setdiff(inputTable.Properties.VariableNames, {'Var1'})), array2table(table2array(inputTable(:,{'Var1'})), 'VariableNames', {'Var1_1', 'Var1_2', 'Var1_3', 'Var1_4', 'Var1_5', 'Var1_6', 'Var1_7', 'Var1_8', 'Var1_9', 'Var1_10', 'Var1_11', 'Var1_12', 'Var1_13', 'Var1_14', 'Var1_15', 'Var1_16', 'Var1_17', 'Var1_18', 'Var1_19', 'Var1_20', 'Var1_21', 'Var1_22', 'Var1_23', 'Var1_24', 'Var1_25', 'Var1_26', 'Var1_27', 'Var1_28', 'Var1_29', 'Var1_30', 'Var1_31', 'Var1_32', 'Var1_33', 'Var1_34', 'Var1_35', 'Var1_36', 'Var1_37', 'Var1_38', 'Var1_39', 'Var1_40', 'Var1_41', 'Var1_42', 'Var1_43', 'Var1_44', 'Var1_45', 'Var1_46', 'Var1_47', 'Var1_48', 'Var1_49', 'Var1_50', 'Var1_51', 'Var1_52', 'Var1_53', 'Var1_54', 'Var1_55', 'Var1_56', 'Var1_57', 'Var1_58', 'Var1_59', 'Var1_60', 'Var1_61', 'Var1_62', 'Var1_63', 'Var1_64', 'Var1_65', 'Var1_66', 'Var1_67', 'Var1_68', 'Var1_69', 'Var1_70', 'Var1_71', 'Var1_72', 'Var1_73', 'Var1_74', 'Var1_75', 'Var1_76', 'Var1_77', 'Var1_78', 'Var1_79', 'Var1_80', 'Var1_81', 'Var1_82', 'Var1_83', 'Var1_84', 'Var1_85', 'Var1_86', 'Var1_87', 'Var1_88', 'Var1_89', 'Var1_90', 'Var1_91', 'Var1_92'})];

predictorNames = {'Var1_1', 'Var1_2', 'Var1_3', 'Var1_4', 'Var1_5', 'Var1_6', 'Var1_7', 'Var1_8', 'Var1_9', 'Var1_10', 'Var1_11', 'Var1_12', 'Var1_13', 'Var1_14', 'Var1_15', 'Var1_16', 'Var1_17', 'Var1_18', 'Var1_19', 'Var1_20', 'Var1_21', 'Var1_22', 'Var1_23', 'Var1_24', 'Var1_25', 'Var1_26', 'Var1_27', 'Var1_28', 'Var1_29', 'Var1_30', 'Var1_31', 'Var1_32', 'Var1_33', 'Var1_34', 'Var1_35', 'Var1_36', 'Var1_37', 'Var1_38', 'Var1_39', 'Var1_40', 'Var1_41', 'Var1_42', 'Var1_43', 'Var1_44', 'Var1_45', 'Var1_46', 'Var1_47', 'Var1_48', 'Var1_49', 'Var1_50', 'Var1_51', 'Var1_52', 'Var1_53', 'Var1_54', 'Var1_55', 'Var1_56', 'Var1_57', 'Var1_58', 'Var1_59', 'Var1_60', 'Var1_61', 'Var1_62', 'Var1_63', 'Var1_64', 'Var1_65', 'Var1_66', 'Var1_67', 'Var1_68', 'Var1_69', 'Var1_70', 'Var1_71', 'Var1_72', 'Var1_73', 'Var1_74', 'Var1_75', 'Var1_76', 'Var1_77', 'Var1_78', 'Var1_79', 'Var1_80', 'Var1_81', 'Var1_82', 'Var1_83', 'Var1_84', 'Var1_85', 'Var1_86', 'Var1_87', 'Var1_88', 'Var1_89', 'Var1_90', 'Var1_91', 'Var1_92'};
predictors = inputTable(:, predictorNames);
response = inputTable.kk;
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, 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];

% Train a classifier
% This code specifies all the classifier options and trains the classifier.
template = templateSVM(...
    'KernelFunction', 'polynomial', ...
    'PolynomialOrder', 3, ...
    'KernelScale', 5, ...
    'BoxConstraint', 1, ...
    'Standardize', true);
classificationSVM = fitcecoc(...
    predictors, ...
    response, ...
    'Learners', template, ...
    'Coding', 'onevsone', ...
    'ClassNames', ['a'; 'b'; 'c'; 'd']);

% Create the result struct with predict function
splitMatricesInTableFcn = @(t) [t(:,setdiff(t.Properties.VariableNames, {'Var1'})), array2table(table2array(t(:,{'Var1'})), 'VariableNames', {'Var1_1', 'Var1_2', 'Var1_3', 'Var1_4', 'Var1_5', 'Var1_6', 'Var1_7', 'Var1_8', 'Var1_9', 'Var1_10', 'Var1_11', 'Var1_12', 'Var1_13', 'Var1_14', 'Var1_15', 'Var1_16', 'Var1_17', 'Var1_18', 'Var1_19', 'Var1_20', 'Var1_21', 'Var1_22', 'Var1_23', 'Var1_24', 'Var1_25', 'Var1_26', 'Var1_27', 'Var1_28', 'Var1_29', 'Var1_30', 'Var1_31', 'Var1_32', 'Var1_33', 'Var1_34', 'Var1_35', 'Var1_36', 'Var1_37', 'Var1_38', 'Var1_39', 'Var1_40', 'Var1_41', 'Var1_42', 'Var1_43', 'Var1_44', 'Var1_45', 'Var1_46', 'Var1_47', 'Var1_48', 'Var1_49', 'Var1_50', 'Var1_51', 'Var1_52', 'Var1_53', 'Var1_54', 'Var1_55', 'Var1_56', 'Var1_57', 'Var1_58', 'Var1_59', 'Var1_60', 'Var1_61', 'Var1_62', 'Var1_63', 'Var1_64', 'Var1_65', 'Var1_66', 'Var1_67', 'Var1_68', 'Var1_69', 'Var1_70', 'Var1_71', 'Var1_72', 'Var1_73', 'Var1_74', 'Var1_75', 'Var1_76', 'Var1_77', 'Var1_78', 'Var1_79', 'Var1_80', 'Var1_81', 'Var1_82', 'Var1_83', 'Var1_84', 'Var1_85', 'Var1_86', 'Var1_87', 'Var1_88', 'Var1_89', 'Var1_90', 'Var1_91', 'Var1_92'})];
extractPredictorsFromTableFcn = @(t) t(:, predictorNames);
predictorExtractionFcn = @(x) extractPredictorsFromTableFcn(splitMatricesInTableFcn(x));
svmPredictFcn = @(x) predict(classificationSVM, x);
trainedClassifier.predictFcn = @(x) svmPredictFcn(predictorExtractionFcn(x));

% Add additional fields to the result struct
trainedClassifier.RequiredVariables = {'Var1'};
trainedClassifier.ClassificationSVM = classificationSVM;
trainedClassifier.About = 'This struct is a trained classifier exported from Classification Learner R2016a.';
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. ''trainedClassifier''. \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
% classifier.
inputTable = trainingData;
% Split matrices in the input table into vectors
inputTable = [inputTable(:,setdiff(inputTable.Properties.VariableNames, {'Var1'})), array2table(table2array(inputTable(:,{'Var1'})), 'VariableNames', {'Var1_1', 'Var1_2', 'Var1_3', 'Var1_4', 'Var1_5', 'Var1_6', 'Var1_7', 'Var1_8', 'Var1_9', 'Var1_10', 'Var1_11', 'Var1_12', 'Var1_13', 'Var1_14', 'Var1_15', 'Var1_16', 'Var1_17', 'Var1_18', 'Var1_19', 'Var1_20', 'Var1_21', 'Var1_22', 'Var1_23', 'Var1_24', 'Var1_25', 'Var1_26', 'Var1_27', 'Var1_28', 'Var1_29', 'Var1_30', 'Var1_31', 'Var1_32', 'Var1_33', 'Var1_34', 'Var1_35', 'Var1_36', 'Var1_37', 'Var1_38', 'Var1_39', 'Var1_40', 'Var1_41', 'Var1_42', 'Var1_43', 'Var1_44', 'Var1_45', 'Var1_46', 'Var1_47', 'Var1_48', 'Var1_49', 'Var1_50', 'Var1_51', 'Var1_52', 'Var1_53', 'Var1_54', 'Var1_55', 'Var1_56', 'Var1_57', 'Var1_58', 'Var1_59', 'Var1_60', 'Var1_61', 'Var1_62', 'Var1_63', 'Var1_64', 'Var1_65', 'Var1_66', 'Var1_67', 'Var1_68', 'Var1_69', 'Var1_70', 'Var1_71', 'Var1_72', 'Var1_73', 'Var1_74', 'Var1_75', 'Var1_76', 'Var1_77', 'Var1_78', 'Var1_79', 'Var1_80', 'Var1_81', 'Var1_82', 'Var1_83', 'Var1_84', 'Var1_85', 'Var1_86', 'Var1_87', 'Var1_88', 'Var1_89', 'Var1_90', 'Var1_91', 'Var1_92'})];

predictorNames = {'Var1_1', 'Var1_2', 'Var1_3', 'Var1_4', 'Var1_5', 'Var1_6', 'Var1_7', 'Var1_8', 'Var1_9', 'Var1_10', 'Var1_11', 'Var1_12', 'Var1_13', 'Var1_14', 'Var1_15', 'Var1_16', 'Var1_17', 'Var1_18', 'Var1_19', 'Var1_20', 'Var1_21', 'Var1_22', 'Var1_23', 'Var1_24', 'Var1_25', 'Var1_26', 'Var1_27', 'Var1_28', 'Var1_29', 'Var1_30', 'Var1_31', 'Var1_32', 'Var1_33', 'Var1_34', 'Var1_35', 'Var1_36', 'Var1_37', 'Var1_38', 'Var1_39', 'Var1_40', 'Var1_41', 'Var1_42', 'Var1_43', 'Var1_44', 'Var1_45', 'Var1_46', 'Var1_47', 'Var1_48', 'Var1_49', 'Var1_50', 'Var1_51', 'Var1_52', 'Var1_53', 'Var1_54', 'Var1_55', 'Var1_56', 'Var1_57', 'Var1_58', 'Var1_59', 'Var1_60', 'Var1_61', 'Var1_62', 'Var1_63', 'Var1_64', 'Var1_65', 'Var1_66', 'Var1_67', 'Var1_68', 'Var1_69', 'Var1_70', 'Var1_71', 'Var1_72', 'Var1_73', 'Var1_74', 'Var1_75', 'Var1_76', 'Var1_77', 'Var1_78', 'Var1_79', 'Var1_80', 'Var1_81', 'Var1_82', 'Var1_83', 'Var1_84', 'Var1_85', 'Var1_86', 'Var1_87', 'Var1_88', 'Var1_89', 'Var1_90', 'Var1_91', 'Var1_92'};
predictors = inputTable(:, predictorNames);
response = inputTable.kk;
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, 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];

% Perform cross-validation
partitionedModel = crossval(trainedClassifier.ClassificationSVM, 'KFold', 5);

% Compute validation accuracy
validationAccuracy = 1 - kfoldLoss(partitionedModel, 'LossFun', 'ClassifError');

% Compute validation predictions and scores
[validationPredictions, validationScores] = kfoldPredict(partitionedModel);
