"""Plot global rankings of learning methods and validators across several scenario evaluation results (implements the script ``diles-rank-evaluation-results``).""" from __future__ import division from itertools import izip, chain import optparse from diles.scenario.util import ResultDB from diles.learn.eval import Metric from diles.learn.util import relscore from diles import stats from diles.learn.validator import ids as validatornames from diles.scenario import LEARNERS as learnerids from diles.scenario import WRAPPERS as wrapperids LINE = r"%s & %s & %s\\" def metric_without_outliers(l): x = sorted(l) for _ in range(3): if len(x) < 3: break del x[0] del x[-1] return Metric(x) def rank(opts): wpn, wsp = opts.validator_weights results = {} validators = ('dynconf', 'minconf', 'hierarchy') + validatornames results['validators'] = dict((x, 0) for x in validators) results['learners'] = dict((x, []) for x in learnerids) results['wrappers'] = dict((x, []) for x in wrapperids) results['wrappers-nogs'] = dict((x, []) for x in wrapperids) duosdict = lambda: dict(('%s-%s' % (w, l), []) for w in wrapperids for l in learnerids) results['duos'] = duosdict() results['runtimes-optimize'] = duosdict() results['runtimes-train'] = duosdict() results['runtimes-predict'] = duosdict() mask = dict(opts.mask, order=['randomized']) nr = 0 for fname in opts.rdbl: rdb = ResultDB(fname) for meta, pfl, extra in rdb.filter(mask): del pfl[:10] nr += 1 validatorscores = [] for vld in validators: mpreneg = "%spreneg" % vld msuppos = "%ssuppos" % vld preneg = Metric(Metric(m).mean for m in izip(*(getattr(pf, mpreneg) for pf in pfl))) suppos = Metric(Metric(m).mean for m in izip(*(getattr(pf, msuppos) for pf in pfl))) validatorscores.append((vld, wpn * preneg.mean + wsp * suppos.mean)) validatorscores = relscore(validatorscores) for k, v in validatorscores: results['validators'][k] += v m = Metric(chain(*(getattr(pf, opts.metric) for pf in pfl))).mean results['learners'][meta['learner']].append(m) if meta['learner'] != 'gs': results['wrappers-nogs'][meta['wrapper']].append(m) results['wrappers'][meta['wrapper']].append(m) duo = '%s-%s' % (meta['wrapper'], meta['learner']) results['duos'][duo].append(m) results['runtimes-optimize'][duo].append(metric_without_outliers(extra['runtimes']['optimize']).mean) results['runtimes-train'][duo].append(metric_without_outliers(extra['runtimes']['train']).mean) results['runtimes-predict'][duo].append(metric_without_outliers(extra['runtimes']['predict']).mean) for rtype, rvalues in results.items(): if rtype in ('validators'): for k, v in rvalues.items(): rvalues[k] = (v/nr, nr) rvalues = rvalues.items() elif rtype.startswith('runtimes-'): for k, l in rvalues.items(): l = sorted(x * 1000 for x in l) # milliseconds, sorted # remove the 3 smallest and greatest outliers for _ in range(3): if len(l) < 3: break del l[0] del l[-1] rvalues[k] = (stats.mean(l), stats.ci(l)) if l else (0, 0) rvalues = rvalues.items() else: for k, l in rvalues.items(): rvalues[k] = (stats.mean(l), stats.ci(l)) if l else (0, 0) rvalues = rvalues.items() #rvalues = relscore(rvalues.items()) #rvalues = [(x[0], (x[1], 1)) for x in rvalues] rvalues = sorted(rvalues, key=lambda x: x[1], reverse=True) results[rtype] = rvalues return results # ============================================================================= # command line interface # ============================================================================= def options(): op = optparse.OptionParser("%prog -d DEST RDB [RDB [...]]") op.add_option("-d", "--dest", metavar="FILE", help="destination file for results") op.add_option("-m", "--mask", metavar="MASK", action="append", default=[], help="only consider results matching this mask (may be " "specified multiple times, each in the format `key:value`)") op.add_option("", "--validator-weights", metavar="W1,W2", default="1.0,1.0", help="weights for prevented negative and suported positive " "predictions (default: 1.0,1.0)") op.add_option("", "--metric", metavar="METRIC", default="match", help="metric for ranks of learners and wrappers " "(default: 1.0,1.0)") opts, fnames = op.parse_args() opts.rdbl = fnames opts.mask = (x.split(":", 1) for x in opts.mask) opts.mask = dict((k, v.split(",")) for k, v in opts.mask) opts.validator_weights = [float(x) for x in opts.validator_weights.split(",")] return opts def main(): opts = options() results = rank(opts) for rtype, rvalues in results.items(): print((" %s " % rtype).center(79, "-")) for item, (val1, val2) in rvalues: print("%-40s: %.3f / %.3f" % (item, val1, val2)) print for rtype, rvalues in results.items(): print((" %s " % rtype).center(79, "-")) for item, (val1, val2) in rvalues: # if rtype in ('learners', 'wrappers', 'duos'): # print(r"%s & %.2f \rankingsd{%.2f}\\" % (item.upper(), val1, val2)) # else: # print(r"%s & %.2f \rankingsd{%d}\\" % (item, val1, int(val2))) if rtype in ('validators'): print(r"%s & %.2f\\" % (item, val1)) elif rtype.startswith('runtimes-'): if rtype == 'runtimes-optimize': unit = 's' val1, val2 = val1 / 1000, val2 / 1000 else: unit = 'ms' print(r"%s & %.2f%s \rankingsd{%.2f}\\" % (item.upper(), val1, unit, val2)) else: print(r"%s & %.2f \rankingsd{%.2f}\\" % (item.upper(), val1, val2)) if __name__ == '__main__': main()