%% matlab_demo_16.m
%%
%% CSS 581, Introduction to Machine Learning, Winter 2014
%% Computing & Software Systems, University of Washington Bothell
%% written by J. Jeffry Howbert, 2012-03-04

%% demo of neural network and support vector machine classification of spoken vowels

%%*************** WARNING ***************
%%** All matrices and vectors need to be transposed for
%%** neural network toolbox!  Samples are in columns and
%%** features are in rows!
%%***************************************

clear all;
close all;
format compact;

load vowel-context.data;
% keep gender and 9 speech features in feature set
data = vowel_context( :, 4 : 13 );
label = vowel_context( :, 14 );
% convert class labels 0-10 to group labels 1-11 for later ease of indexing
label = grp2idx( label );
nClass = max( label );
trainData = data( vowel_context( :, 1 ) == 0, : );
trainLabel = label( vowel_context( :, 1 ) == 0, : );
testData = data( vowel_context( :, 1 ) == 1, : );
testLabel = label( vowel_context( :, 1 ) == 1, : );
nTrain = length( trainLabel );
nTest = length( testLabel );
% convert group labels to dummy variable arrays
trainLabelDum = dummyvar( trainLabel );
testLabelDum = dummyvar( testLabel );

%% ***** run neural network multiclass classification
%% All matrices and vectors need to be transposed for
%%  neural network toolbox!
trainData = trainData';
testData = testData';
trainLabel = trainLabel';
testLabel = testLabel';
trainLabelDum = trainLabelDum';
testLabelDum = testLabelDum';

nRand = 10;
nHid = 5;
hiddenTransferFcn = 'tansig';   % 'tansig' or 'logsig'
outputTransferFcn = 'purelin';   % 'purelin' or 'tansig' or 'logsig'
testPred = zeros( nClass, nTest );
% run ensemble of nRand neural networks, use sum of predicted outputs over ensemble to predict class
for ra = 1 : nRand
    RandStream.setGlobalStream( RandStream( 'mt19937ar', 'seed', ra ) );
    net = newff( trainData, trainLabelDum, nHid );
    net.layers{ 1 }.transferFcn = hiddenTransferFcn;
    net.layers{ 2 }.transferFcn = outputTransferFcn;
    net.trainParam.showWindow = false;
    net.trainParam.showCommandLine = false;
    net = train( net, trainData, trainLabelDum );
    % sum up output predictions (real values) for the 11 classes over ensemble
    testPred = testPred + sim( net, testData );
end
% convert sums of outputs to class prediction
[ ~, testLabelPred ] = max( testPred );
%% *****

% %% ***** run LIBSVM support vector machine multiclass classification
% model = svmtrain( trainLabel, trainData );
% [ testLabelPred, ~, ~ ] = svmPredict( testLabel, testData, model );
% %% *****

nTestPredCorrect = sum( testLabelPred == testLabel );
fprintf( 1, 'test set correct predictions = %d / %d\n\n', nTestPredCorrect, nTest );

[ mat, order ] = confusionmat( testLabel, testLabelPred );
disp( order' );
disp( ' ' );
disp( mat );
