view 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 source
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