Mercurial > hg > aasp-d-case-metrics
changeset 0:2c9915c861d8
First version
author | emmanouilb <emmanouil.benetos.1@city.ac.uk> |
---|---|
date | Fri, 08 Mar 2013 11:33:20 +0000 |
parents | |
children | c8924e29f1aa |
files | event_detection/convertEventListToEventRoll.m event_detection/eventDetectionMetrics_classWiseEventBased.m event_detection/eventDetectionMetrics_eventBased.m event_detection/eventDetectionMetrics_frameBased.m event_detection/loadEventsList.m scene_classification/fold1_test_ubhjwk.txt scene_classification/foldGTlist.txt scene_classification/foldtestlist.txt scene_classification/loadClassificationOutput.m scene_classification/sceneClassificationMetrics_eval.m |
diffstat | 10 files changed, 318 insertions(+), 0 deletions(-) [+] |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/event_detection/convertEventListToEventRoll.m Fri Mar 08 11:33:20 2013 +0000 @@ -0,0 +1,17 @@ +function [eventRoll] = convertEventListToEventRoll(onset,offset,classNames) + + +% Initialize +eventRoll = zeros(ceil(offset(length(offset))*100),16); +eventID = {'alert','clearthroat','cough','doorslam','drawer','keyboard','keys',... + 'knock','laughter','mouse','pageturn','pendrop','phone','printer','speech','switch'}; + + +% Fill-in eventRoll +for i=1:length(onset) + + pos = strmatch(classNames{i}, eventID); + + eventRoll(floor(onset(i)*100):ceil(offset(i)*100),pos) = 1; + +end;
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/event_detection/eventDetectionMetrics_classWiseEventBased.m Fri Mar 08 11:33:20 2013 +0000 @@ -0,0 +1,80 @@ +function [results] = eventDetectionMetrics_classWiseEventBased(outputFile,GTFile) + +% Class-wise event-based evaluation for event detection task +% outputFile: the output of the event detection system +% GTFile: the ground truth list of events + +% Initialize +eventID = {'alert','clearthroat','cough','doorslam','drawer','keyboard','keys',... + 'knock','laughter','mouse','pageturn','pendrop','phone','printer','speech','switch'}; + + +% Load event list from output and ground-truth +[onset,offset,classNames] = loadEventsList(outputFile); +[onsetGT,offsetGT,classNamesGT] = loadEventsList(GTFile); + + +% Total number of detected and reference events per class +Ntot = zeros(16,1); +for i=1:length(onset) + pos = strmatch(classNames{i}, eventID); + Ntot(pos) = Ntot(pos)+1; +end; + +Nref = zeros(16,1); +for i=1:length(onsetGT) + pos = strmatch(classNamesGT{i}, eventID); + Nref(pos) = Nref(pos)+1; +end; +I = find(Nref>0); % index for classes present in ground-truth + + +% Number of correctly transcribed events per class, onset within a +/-100 ms range +Ncorr = zeros(16,1); +NcorrOff = zeros(16,1); +for j=1:length(onsetGT) + for i=1:length(onset) + + if( strcmp(classNames{i},classNamesGT{j}) && (abs(onsetGT(j)-onset(i))<=0.1) ) + pos = strmatch(classNames{i}, eventID); + Ncorr(pos) = Ncorr(pos)+1; + + % If offset within a +/-100 ms range or within 50% of ground-truth event's duration + if abs(offsetGT(j) - offset(i)) <= max(0.1, 0.5 * (offsetGT(j) - onsetGT(j))) + pos = strmatch(classNames{i}, eventID); + NcorrOff(pos) = NcorrOff(pos) +1; + end; + + break; % In order to not evaluate duplicates + + end; + end; +end; + + +% Compute onset-only class-wise event-based metrics +Nfp = Ntot-Ncorr; +Nfn = Nref-Ncorr; +Nsubs = min(Nfp,Nfn); +tempRec = Ncorr(I)./(Nref(I)+eps); +tempPre = Ncorr(I)./(Ntot(I)+eps); +results.Rec = mean(tempRec); +results.Pre = mean(tempPre); +tempF = 2*((tempPre.*tempRec)./(tempPre+tempRec+eps)); +results.F = mean(tempF); +tempAEER = (Nfn(I)+Nfp(I)+Nsubs(I))./(Nref(I)+eps); +results.AEER = mean(tempAEER); + + +% Compute onset-offset class-wise event-based metrics +NfpOff = Ntot-NcorrOff; +NfnOff = Nref-NcorrOff; +NsubsOff = min(NfpOff,NfnOff); +tempRecOff = NcorrOff(I)./(Nref(I)+eps); +tempPreOff = NcorrOff(I)./(Ntot(I)+eps); +results.RecOff = mean(tempRecOff); +results.PreOff = mean(tempPreOff); +tempFOff = 2*((tempPreOff.*tempRecOff)./(tempPreOff+tempRecOff+eps)); +results.FOff = mean(tempFOff); +tempAEEROff = (NfnOff(I)+NfpOff(I)+NsubsOff(I))./(Nref(I)+eps); +results.AEEROff = mean(tempAEEROff);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/event_detection/eventDetectionMetrics_eventBased.m Fri Mar 08 11:33:20 2013 +0000 @@ -0,0 +1,56 @@ +function [results] = eventDetectionMetrics_eventBased(outputFile,GTFile) + +% Event-based evaluation for event detection task +% outputFile: the output of the event detection system +% GTFile: the ground truth list of events + +% Load event list from output and ground-truth +[onset,offset,classNames] = loadEventsList(outputFile); +[onsetGT,offsetGT,classNamesGT] = loadEventsList(GTFile); + + +% Total number of detected and reference events +Ntot = length(onset); +Nref = length(onsetGT); + + +% Number of correctly transcribed events, onset within a +/-100 ms range +Ncorr = 0; +NcorrOff = 0; +for j=1:length(onsetGT) + for i=1:length(onset) + + if( strcmp(classNames{i},classNamesGT{j}) && (abs(onsetGT(j)-onset(i))<=0.1) ) + Ncorr = Ncorr+1; + + % If offset within a +/-100 ms range or within 50% of ground-truth event's duration + if abs(offsetGT(j) - offset(i)) <= max(0.1, 0.5 * (offsetGT(j) - onsetGT(j))) + NcorrOff = NcorrOff +1; + end; + + break; % In order to not evaluate duplicates + + end; + end; + +end; + + +% Compute onset-only event-based metrics +Nfp = Ntot-Ncorr; +Nfn = Nref-Ncorr; +Nsubs = min(Nfp,Nfn); +results.Rec = Ncorr/(Nref+eps); +results.Pre = Ncorr/(Ntot+eps); +results.F = 2*((results.Pre*results.Rec)/(results.Pre+results.Rec+eps)); +results.AEER= (Nfn+Nfp+Nsubs)/(Nref+eps); + + +% Compute onset-offset event-based metrics +NfpOff = Ntot-NcorrOff; +NfnOff = Nref-NcorrOff; +NsubsOff = min(NfpOff,NfnOff); +results.RecOff = NcorrOff/(Nref+eps); +results.PreOff = NcorrOff/(Ntot+eps); +results.FOff = 2*((results.PreOff*results.RecOff)/(results.PreOff+results.RecOff+eps)); +results.AEEROff= (NfnOff+NfpOff+NsubsOff)/(Nref+eps);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/event_detection/eventDetectionMetrics_frameBased.m Fri Mar 08 11:33:20 2013 +0000 @@ -0,0 +1,34 @@ +function [results] = eventDetectionMetrics_frameBased(outputFile,GTFile) + +% Frame-based evaluation for event detection task +% outputFile: the output of the event detection system +% GTFile: the ground truth list of events + +% Load event list from output and ground-truth +[onset,offset,classNames] = loadEventsList(outputFile); +[onsetGT,offsetGT,classNamesGT] = loadEventsList(GTFile); + + +% Convert event list into frame-based representation (10msec resolution) +[eventRoll] = convertEventListToEventRoll(onset,offset,classNames); +[eventRollGT] = convertEventListToEventRoll(onsetGT,offsetGT,classNamesGT); + + +% Fix durations of eventRolls +if (size(eventRollGT,1) > size(eventRoll,1)) eventRoll = [eventRoll; zeros(size(eventRollGT,1)-size(eventRoll,1),16)]; end; +if (size(eventRoll,1) > size(eventRollGT,1)) eventRollGT = [eventRollGT; zeros(size(eventRoll,1)-size(eventRollGT,1),16)]; end; + + +% Compute frame-based metrics +Nref = sum(sum(eventRollGT)); +Ntot = sum(sum(eventRoll)); +Ntp = sum(sum(eventRoll+eventRollGT > 1)); +Nfp = sum(sum(eventRoll-eventRollGT > 0)); +Nfn = sum(sum(eventRollGT-eventRoll > 0)); +Nsubs = min(Nfp,Nfn); + + +results.Rec = Ntp/(Nref+eps); +results.Pre = Ntp/(Ntot+eps); +results.F = 2*((results.Pre*results.Rec)/(results.Pre+results.Rec+eps)); +results.AEER = (Nfn+Nfp+Nsubs)/(Nref+eps);
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/event_detection/loadEventsList.m Fri Mar 08 11:33:20 2013 +0000 @@ -0,0 +1,27 @@ +function [onset,offset,classNames] = loadEventsList(filename) + +% Open raw file +fid = fopen(filename,'r+'); + +% Read 1st line +tline = fgetl(fid); +onset_offset(:,1) = sscanf(tline, '%f\t%f\t%*s'); +classNames{1} = char(sscanf(tline, '%*f\t%*f\t%s')'); + +% Read rest of the lines +i=1; +while ischar(tline) + i = i+1; + tline = fgetl(fid); + if (ischar(tline)) + onset_offset(:,i) = sscanf(tline, '%f\t%f\t%*s'); + classNames{i} = char(sscanf(tline, '%*f\t%*f\t%s')'); + end; +end + +% Split onset_offset +onset = onset_offset(1,:)'; +offset = onset_offset(2,:)'; + +% Close file +fclose(fid); \ No newline at end of file
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scene_classification/fold1_test_ubhjwk.txt Fri Mar 08 11:33:20 2013 +0000 @@ -0,0 +1,20 @@ +tmp/1_lsiknx/1_qnsnmm.wav bus +tmp/1_lsiknx/6_jvgwsj.wav restaurant +tmp/1_lsiknx/1_itqeyo.wav busystreet +tmp/1_lsiknx/6_okasnj.wav busystreet +tmp/1_lsiknx/1_xctssd.wav office +tmp/1_lsiknx/6_hudnps.wav office +tmp/1_lsiknx/1_zzdynb.wav quietstreet +tmp/1_lsiknx/6_uisfys.wav quietstreet +tmp/1_lsiknx/1_qrgvha.wav restaurant +tmp/1_lsiknx/6_dxhmur.wav restaurant +tmp/1_lsiknx/1_cglqsz.wav supermarket +tmp/1_lsiknx/6_nglrop.wav supermarket +tmp/1_lsiknx/1_mjugvv.wav openairmarket +tmp/1_lsiknx/6_fhtnxb.wav openairmarket +tmp/1_lsiknx/1_bmdzly.wav park +tmp/1_lsiknx/6_tuhcjv.wav supermarket +tmp/1_lsiknx/1_yyzbli.wav tubestation +tmp/1_lsiknx/6_qvnesx.wav tube +tmp/1_lsiknx/1_bjscrh.wav tubestation +tmp/1_lsiknx/6_upmhdh.wav tubestation
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scene_classification/foldGTlist.txt Fri Mar 08 11:33:20 2013 +0000 @@ -0,0 +1,5 @@ +fold1_testgt_ubhjwk.txt +fold2_testgt_stxbia.txt +fold3_testgt_bcbkdl.txt +fold4_testgt_bdbtlr.txt +fold5_testgt_mdbsir.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scene_classification/foldtestlist.txt Fri Mar 08 11:33:20 2013 +0000 @@ -0,0 +1,5 @@ +fold1_test_ubhjwk.txt +fold2_test_stxbia.txt +fold3_test_bcbkdl.txt +fold4_test_bdbtlr.txt +fold5_test_mdbsir.txt
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scene_classification/loadClassificationOutput.m Fri Mar 08 11:33:20 2013 +0000 @@ -0,0 +1,26 @@ +function [fileID,classID] = loadClassificationOutput(filename) + +% Open raw file +fid = fopen(filename,'r+'); + +% Read 1st line +tline = fgetl(fid); +fileID{1} = char(sscanf(tline, '%s\t%*s')); +classID{1} = char(sscanf(tline, '%*s\t%s')); + +% Read rest of the lines +i=1; +while ischar(tline) + i = i+1; + tline = fgetl(fid); + if (ischar(tline)) + + fileID{i} = char(sscanf(tline, '%s\t%*s')); + classID{i} = char(sscanf(tline, '%*s\t%s')); + + end; +end + +% Close file +fclose(fid); +
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/scene_classification/sceneClassificationMetrics_eval.m Fri Mar 08 11:33:20 2013 +0000 @@ -0,0 +1,48 @@ +function [confusionMat, AccFolds, Acc, Std] = sceneClassificationMetrics_eval(numfolds, foldsGTlist, foldstestlist) + +% Function takes as input a number of folds (numfolds), a text file +% containing a list of filenames with the ground truth per fold (foldsGTlist), +% and a text file containing a list of filenames with the classification +% output (foldstestlist) +% +% e.g. [confusionMat, AccFolds, Acc, Std] = sceneClassificationMetrics_eval(5, 'foldGTlist.txt', 'foldtestlist.txt'); + + +% Initialize +classList = {'bus','busystreet','office','openairmarket','park','quietstreet','restaurant','supermarket','tube','tubestation'}; +confusionMat = zeros(10,10); +AccFolds = zeros(1,numfolds); + + +% For each fold +fid1 = fopen(foldsGTlist,'r+'); +fid2 = fopen(foldstestlist,'r+'); +for i=1:numfolds + + % Load classification output and ground truth + tline1 = fgetl(fid1); + [fileIDGT,classIDGT] = loadClassificationOutput(tline1); + tline2 = fgetl(fid2); + [fileID,classID] = loadClassificationOutput(tline2); + + % Compute confusion matrix per fold + confusionMatTemp = zeros(10,10); + for j=1:length(classIDGT) + pos = strmatch(fileIDGT{j}, fileID, 'exact'); + posClassGT = strmatch(classIDGT{j}, classList, 'exact'); + posClass = strmatch(classID{pos}, classList, 'exact'); + confusionMatTemp(posClassGT,posClass) = confusionMatTemp(posClassGT,posClass) + 1; + end + + % Compute accuracy per fold + AccFolds(i) = sum(diag(confusionMatTemp))/sum(sum(confusionMatTemp)); + confusionMat = confusionMat + confusionMatTemp; + +end +fclose(fid1); +fclose(fid2); + + +% Compute global accuracy and std +Acc = mean(AccFolds); +Std = std(AccFolds);