annotate testdata/scripts/evaluate_lab.yeti @ 372:af71cbdab621 tip

Update bqvec code
author Chris Cannam
date Tue, 19 Nov 2019 10:13:32 +0000
parents 7cb021e40732
children
rev   line source
Chris@138 1
Chris@138 2 // Take two lab files of the form
Chris@138 3 //
Chris@138 4 // onset offset frequency
Chris@138 5 //
Chris@138 6 // and report their onset-only note-level accuracy F-measure.
Chris@138 7
Chris@138 8 program evaluate_lab;
Chris@138 9
Chris@138 10 usage () =
Chris@138 11 (eprintln "\nUsage: evaluate_lab reqd reference.lab transcribed.lab\n";
Chris@138 12 eprintln "where reqd is the number of milliseconds allowed for timing error (+/-)\n");
Chris@138 13
Chris@138 14 toMIDIPitch f =
Chris@138 15 round (12 * (Math#log(f / 220) / Math#log(2)) + 57);
Chris@138 16
Chris@138 17 suck f =
Chris@138 18 (str = openInFile f "UTF-8"; // better to use readFile here, oh well
Chris@138 19 d = map do line:
Chris@138 20 case list (strSplit "\t" line) of
Chris@138 21 onset::offset::frequency::_:
Chris@138 22 { onset = number onset, midi = toMIDIPitch (number frequency) };
Chris@138 23 _:
Chris@138 24 failWith "badly formed line: \(line)";
Chris@138 25 esac;
Chris@138 26 done (str.lines ());
Chris@138 27 str.close ();
Chris@138 28 d);
Chris@138 29
Chris@138 30 select f = fold do r x: if f x then x::r else r fi done [];
Chris@138 31
Chris@138 32 evaluate permitted ref trans =
Chris@138 33 (reference = suck ref;
Chris@138 34 transcribed = suck trans;
Chris@138 35 accurate =
Chris@138 36 select do here :
Chris@138 37 any do other:
Chris@138 38 here.midi == other.midi and
Chris@138 39 abs (here.onset - other.onset) < permitted
Chris@138 40 done reference
Chris@138 41 done transcribed;
Chris@138 42 {
Chris@138 43 ntot = length transcribed,
Chris@138 44 nref = length reference,
Chris@138 45 ncorr = length accurate,
Chris@138 46 });
Chris@138 47
Chris@138 48 pc n =
Chris@138 49 int (n * 1000) / 10;
Chris@138 50
Chris@138 51 report { ntot, nref, ncorr } =
Chris@138 52 (nfp = ntot - ncorr;
Chris@138 53 nfn = nref - ncorr;
Chris@222 54 if nref == 0 then
Chris@222 55 println "ERROR: no events in reference!"
Chris@222 56 elif ntot == 0 then
Chris@222 57 println "WARNING: no events transcribed!"
Chris@222 58 else
Chris@222 59 rec = ncorr / nref;
Chris@222 60 pre = ncorr / ntot;
Chris@222 61 f = if pre + rec == 0 then 0 else 2 * ((pre * rec) / (pre + rec)) fi;
Chris@222 62 acc = ncorr / (ncorr + nfp + nfn);
Chris@222 63 println "precision \(pc pre), recall \(pc rec), accuracy \(pc acc), F \(pc f)";
Chris@222 64 fi);
Chris@138 65
Chris@138 66 case (list _argv) of
Chris@138 67 reqd::ref::trans::[]: report (evaluate (number reqd / 1000) ref trans);
Chris@138 68 _: usage ();
Chris@138 69 esac;
Chris@138 70