Mercurial > hg > emotion-detection-top-level
diff Code/Classifiers/SVM_Singing.m @ 4:92ca03a8fa99 tip
Update to ICASSP 2013 benchmark
author | Dawn Black |
---|---|
date | Wed, 13 Feb 2013 11:02:39 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Code/Classifiers/SVM_Singing.m Wed Feb 13 11:02:39 2013 +0000 @@ -0,0 +1,242 @@ +function [] = SVM_Singing( inputFileName ) + +cd 'C:\Users\dawn\Dropbox\TestResults' + +DEBUG = 1; +% output results file name +% masterFileOutputID = fopen( 'SVM_Singing_HNR.txt', 'a' ); +outputFileName = ['SVM_' inputFileName]; +masterFileOutputID = fopen( outputFileName, 'a' ); + +% input results file name +% inputFileName = 'singingBasicHNRStats.txt'; + +fprintf( masterFileOutputID, '\n RESULTS FILE NAME: %s\n', inputFileName); +inputFileID = fopen( inputFileName ); + +% noOfArguments = length(varargin); + +% outputFileName = 'individualResults/SVM_Results_'; +% resultsFileName = 'SVM_Results_'; +titleName = ''; +% for i=1 : noOfArguments +% titleName = [ titleName varargin{i} '_']; +% fprintf( masterFileOutputID, '%s_', varargin{i} ); +% end + +% outputFileName = [ outputFileName titleName ]; +% resultsFileName = [ resultsFileName titleName ]; + +fprintf( masterFileOutputID, '\t' ); + +% outputFileName = [ outputFileName '.txt']; +% resultsFileName = [ resultsFileName '.txt']; +% +% fileOutputID = fopen( outputFileName, 'w' ); +% fileSVMOutputID = fopen( resultsFileName, 'w' ); + +% -------------------- get the data from the results file --------------- +lineCount = 0; +fileCount = 0; +data = []; +groups = []; + +while( ~(feof(inputFileID)) ) + + outputValues = []; + thestr = fgetl(inputFileID); + fileCount = fileCount + 1; + + % determine whether we have a positive or negative sample + sampleEmotion( fileCount ) = 'U'; + if( ~(isempty(strfind(thestr,'pos')))) + % sample is positive + sampleEmotion( fileCount ) = 'P'; + groups( fileCount ) = 1; + elseif( ~(isempty(strfind(thestr,'neg')))) + % sample is negative + sampleEmotion( fileCount ) = 'N'; + groups( fileCount ) = 0; + else + disp('EEEK!'); + fileCount = fileCount - 1; +% pause; + end + + % determine whether we have a male, female or trans sample +% gender( fileCount ) = '?'; +% if( ~(isempty(strfind(thestr,'fem')))) +% % gender is female +% gender( fileCount ) = 'F'; +% elseif( ~(isempty(strfind(thestr,'male')))) +% % gender is male +% gender( fileCount ) = 'M'; +% elseif( ~(isempty(strfind(thestr,'trans')))) +% % gender is trans +% gender( fileCount ) = 'T'; +% else +% disp('EEEK!'); +% pause; +% end + + if(( ~(isempty(strfind(thestr,'pos')))) || ( ~(isempty(strfind(thestr,'neg')))) ) + %how many values are in the string? +% spaces = strfind( thestr, ' ' ); + spaces = [ strfind( thestr, sprintf('\t')) strfind( thestr, ' ' )]; + numberstr = thestr( spaces(1) : end ); % chop off the file name + vars = sscanf( numberstr, '%f', inf ); + data( fileCount, : ) = vars; + end + + lineCount = lineCount + 1; + +end +fclose(inputFileID); + +% ------------ apply the SVM classifier ------------------------ + +resultMatrix = []; + +noOfIterations = 100; + +for n = 1:noOfIterations + % Randomly select training and test sets, perhaps we should try all and + % choose the best? + [train, test] = crossvalind('holdOut',groups); + cp = classperf(groups); + + % Use a linear support vector machine classifier + svmStruct = svmtrain(data(train,:),groups(train)); + classes = svmclassify(svmStruct,data(test,:)); + % See how well the classifier performed + classperf(cp,classes,test); + numbers = cp.CountingMatrix; + + resultMatrix (n,:,:) = cp.DiagnosticTable; +% +end + + + + +% for emotion detection give the confusion matrix as + % ----------------------------------------------------------------- + % positive correctly identified | positive incorrectly identified (1,2) + % negative incorrectly identified (2,1) | negative correctly identified + % ------------------------------------------------------------------ + +% takes the average of 100 iterations - do we want to take the best? + +meanResults(1,1) = mean( resultMatrix(:,1,1) ); +meanResults(1,2) = mean( resultMatrix(:,2,1) ); +meanResults(2,1) = mean( resultMatrix(:,1,2) ); +meanResults(2,2) = mean( resultMatrix(:,2,2) ); + +meanResults(3,:)=0; +meanResults(:,3)=0; + +meanResults(3,3) = (meanResults(1,1) + meanResults(2,2));% / sum(sum(meanResults)); + +% convert to percentages +% how many of each sample do we have? +groupNumbers = unique( groups( test )); +groupNames = unique( sampleEmotion( test )); +sampleEmotionTest = sampleEmotion( test ); +% which group is which emotion? +thisGroupNumber = groupNumbers(1); +thisGroup = find( groups( test ) == thisGroupNumber ); +thisGroupName = unique( sampleEmotionTest( thisGroup )); + +thatGroupNumber = groupNumbers(2); +thatGroup = find( groups( test ) == thatGroupNumber ); +thatGroupName = unique( sampleEmotionTest( thatGroup )); + +if(length( thisGroupName ) ~= 1 ) + disp('ARGH!'); + pause; +end + +thisGroupNumberOfSamples = length( thisGroup ); +thatGroupNumberOfSamples = length( thatGroup ); + +if( thisGroupName == 'P' ) + %swap all the variables ready for checking + temp = thisGroupNumberOfSamples; + thisGroupNumberOfSamples = thatGroupNumberOfSamples; + thatGroupNumberOfSamples = temp; + + temp = thisGroupName; + thisGroupName = thatGroupName + thatGroupName = temp; + disp('CHECK ME!'); +end + +if( thisGroupName == 'N' ) + % group 0 is negative + if( sum( meanResults(1,:) ) == thisGroupNumberOfSamples ) + %if the elements in the first row add up to the number of negative + %samples, then swap the rows because we want the top row to be the + %results for the positive samples + temp(:,1) = meanResults(1:2,2); + temp(:,2) = meanResults(1:2,1); + temp2(1,:) = temp(2,:); + temp2(2,:) = temp(1,:); + + meanResults(1:2,1) = temp2(:,1); + meanResults(1:2,2) = temp2(:,2); + + % check the number of positive samples + if(( sum( meanResults(1,:) ) == thatGroupNumberOfSamples ) ... + && ( thatGroupName == 'P' ) ) + % row 1 is positive + disp('matrix correct'); + else + disp('ARGH!'); + pause; + end + + elseif( sum( meanResults(2,:) ) == thisGroupNumberOfSamples ) + + % the elements in the second row add up to the number of negative + % samples, so the matrix is the correct way around + + % check the number of positive samples + if(( sum( meanResults(1,:) ) == thatGroupNumberOfSamples ) ... + && ( thatGroupName == 'P' ) ) + % row 0 is positive + disp('matrix correct'); + else + disp('ARGH!'); + pause; + end + end +end + +% calculate the percentages +numberOfSamples = sum(sum( meanResults(1:2,1:2))); +percentageResults = meanResults; +percentageResults(1,1) = meanResults(1,1) / numberOfSamples; +percentageResults(1,2) = meanResults(1,2) / numberOfSamples; +percentageResults(2,1) = meanResults(2,1) / numberOfSamples; +percentageResults(2,2) = meanResults(2,2) / numberOfSamples; +percentageResults(3,3) = meanResults(3,3) / numberOfSamples; + +percentageResults = percentageResults * 100 + +confusionMatrix = percentageResults; + fprintf( masterFileOutputID, '\n %f \t %f \n %f \t %f \n %f \t %f \t %f \n', confusionMatrix(1,1), confusionMatrix(1,2), confusionMatrix(2,1), confusionMatrix(2,2), 0, 0, confusionMatrix(3,3)); + + % print latex results to the screen +str1 = sprintf(' & %2.2f & %2.2f & \\\\', percentageResults(1,1), percentageResults(1,2) ); +disp(str1); +str1 = sprintf(' & %2.2f & %2.2f & \\\\', percentageResults(2,1), percentageResults(2,2) ); +disp(str1); +str1 = sprintf(' & & & %2.2f \\\\',percentageResults(3,3) ); +disp(str1); + +fprintf( masterFileOutputID, '\n' ); +fclose( masterFileOutputID ); + +end + +