annotate testdata/evaluation/evaluate_lab.yeti @ 167:416b555df3b2 finetune

More on returning fine tuning (but we're treating different shifts of the same pitch as different notes at the moment which is not right)
author Chris Cannam
date Tue, 20 May 2014 17:49:07 +0100
parents c0802d1b1fad
children 69ac2d0770b8
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@138 54 rec = ncorr / nref;
Chris@138 55 pre = ncorr / ntot;
Chris@138 56 f = 2 * ((pre * rec) / (pre + rec));
Chris@138 57 acc = ncorr / (ncorr + nfp + nfn);
Chris@138 58 println "precision \(pc pre), recall \(pc rec), accuracy \(pc acc), F \(pc f)");
Chris@138 59
Chris@138 60 case (list _argv) of
Chris@138 61 reqd::ref::trans::[]: report (evaluate (number reqd / 1000) ref trans);
Chris@138 62 _: usage ();
Chris@138 63 esac;
Chris@138 64