Commit 0781e166 authored by Theophile GENTILHOMME's avatar Theophile GENTILHOMME

Various small changes after Amir review: add/remove command options, use...

Various small changes after Amir review: add/remove command options, use matplotlib 2.2.2 functionalities, fix doc
parent ab9cd9e7
Pipeline #19137 passed with stage
in 25 minutes and 53 seconds
......@@ -260,7 +260,7 @@ def epc(dev_negatives, dev_positives, test_negatives, test_positives,
return pyplot.plot(out[0, :], 100.0 * out[1, :], **kwargs)
def det(negatives, positives, npoints=100, axisfontsize='x-small', **kwargs):
def det(negatives, positives, npoints=100, **kwargs):
"""Plots Detection Error Trade-off (DET) curve as defined in the paper:
Martin, A., Doddington, G., Kamm, T., Ordowski, M., & Przybocki, M. (1997).
......@@ -381,9 +381,9 @@ def det(negatives, positives, npoints=100, axisfontsize='x-small', **kwargs):
pticks = [ppndf(float(v)) for v in desiredTicks]
ax = pyplot.gca() # and finally we set our own tick marks
ax.set_xticks(pticks)
ax.set_xticklabels(desiredLabels, size=axisfontsize)
ax.set_xticklabels(desiredLabels)
ax.set_yticks(pticks)
ax.set_yticklabels(desiredLabels, size=axisfontsize)
ax.set_yticklabels(desiredLabels)
return retval
......
......@@ -21,16 +21,14 @@ from bob.extension.scripts.click_helper import (verbosity_option,
@verbosity_option()
@click.pass_context
def metrics(ctx, scores, evaluation, **kwargs):
"""Prints a single output line that contains all info for a given
criterion (eer or hter).
"""Prints a table that contains FtA, FAR, FRR, FMR, FMNR, HTER for a given
threshold criterion (eer or hter).
You need provide one or more development score file(s) for each experiment.
You need to provide one or more development score file(s) for each experiment.
You can also provide evaluation files along with dev files. If only dev scores
are provided, you must use flag `--no-evaluation`.
Resulting table format can be changer using the `--tablefmt`. Default
formats are `fancy_grid` when output in the terminal and `latex` when
written in a log file (see `--log`)
Resulting table format can be changed using the `--tablefmt`.
Examples:
$ bob measure metrics dev-scores
......@@ -42,7 +40,6 @@ def metrics(ctx, scores, evaluation, **kwargs):
process = figure.Metrics(ctx, scores, evaluation, load.split_files)
process.run()
@click.command()
@common_options.scores_argument(nargs=-1)
@common_options.title_option()
......@@ -53,12 +50,14 @@ def metrics(ctx, scores, evaluation, **kwargs):
@common_options.points_curve_option()
@common_options.semilogx_option(True)
@common_options.axes_val_option(dflt=[1e-4, 1, 1e-4, 1])
@common_options.axis_fontsize_option()
@common_options.x_rotation_option()
@common_options.x_label_option()
@common_options.y_label_option()
@common_options.lines_at_option()
@common_options.const_layout_option()
@common_options.figsize_option()
@common_options.style_option()
@common_options.const_layout_option()
@verbosity_option()
@click.pass_context
def roc(ctx, scores, evaluation, **kwargs):
......@@ -67,7 +66,7 @@ def roc(ctx, scores, evaluation, **kwargs):
false non match rate on the vertical axis. The values for the axis will be
computed using :py:func:`bob.measure.roc`.
You need provide one or more development score file(s) for each experiment.
You need to provide one or more development score file(s) for each experiment.
You can also provide evaluation files along with dev files. If only dev scores
are provided, you must use flag `--no-evaluation`.
......@@ -82,7 +81,6 @@ def roc(ctx, scores, evaluation, **kwargs):
process = figure.Roc(ctx, scores, evaluation, load.split_files)
process.run()
@click.command()
@common_options.scores_argument(nargs=-1)
@common_options.output_plot_file_option(default_out='det.pdf')
......@@ -91,12 +89,14 @@ def roc(ctx, scores, evaluation, **kwargs):
@common_options.sep_dev_eval_option()
@common_options.eval_option()
@common_options.axes_val_option(dflt=[0.01, 95, 0.01, 95])
@common_options.axis_fontsize_option(dflt=6)
@common_options.x_rotation_option(dflt=45)
@common_options.x_label_option()
@common_options.y_label_option()
@common_options.points_curve_option()
@common_options.const_layout_option()
@common_options.figsize_option()
@common_options.style_option()
@common_options.const_layout_option()
@verbosity_option()
@click.pass_context
def det(ctx, scores, evaluation, **kwargs):
......@@ -104,7 +104,7 @@ def det(ctx, scores, evaluation, **kwargs):
modified ROC curve which plots error rates on both axes
(false positives on the x-axis and false negatives on the y-axis)
You need provide one or more development score file(s) for each experiment.
You need to provide one or more development score file(s) for each experiment.
You can also provide evaluation files along with dev files. If only dev scores
are provided, you must use flag `--no-evaluation`.
......@@ -119,17 +119,18 @@ def det(ctx, scores, evaluation, **kwargs):
process = figure.Det(ctx, scores, evaluation, load.split_files)
process.run()
@click.command()
@common_options.scores_argument(eval_mandatory=True, nargs=-1)
@common_options.output_plot_file_option(default_out='epc.pdf')
@common_options.title_option()
@common_options.titles_option()
@common_options.points_curve_option()
@common_options.axis_fontsize_option()
@common_options.const_layout_option()
@common_options.x_label_option()
@common_options.y_label_option()
@common_options.figsize_option()
@common_options.style_option()
@common_options.const_layout_option()
@verbosity_option()
@click.pass_context
def epc(ctx, scores, **kwargs):
......@@ -138,7 +139,7 @@ def epc(ctx, scores, **kwargs):
a-priori on the development set and accounts for varying relative cost
in [0; 1] of FPR and FNR when calculating the threshold.
You need provide one or more development score and eval file(s)
You need to provide one or more development score and eval file(s)
for each experiment.
Examples:
......@@ -149,27 +150,28 @@ def epc(ctx, scores, **kwargs):
process = figure.Epc(ctx, scores, True, load.split_files)
process.run()
@click.command()
@common_options.scores_argument(nargs=-1)
@common_options.output_plot_file_option(default_out='hist.pdf')
@common_options.eval_option()
@common_options.n_bins_option()
@common_options.criterion_option()
@common_options.axis_fontsize_option()
@common_options.thresholds_option()
@common_options.const_layout_option()
@common_options.show_dev_option()
@common_options.print_filenames_option()
@common_options.title_option()
@common_options.titles_option()
@common_options.figsize_option()
@common_options.style_option()
@common_options.const_layout_option()
@verbosity_option()
@click.pass_context
def hist(ctx, scores, evaluation, **kwargs):
""" Plots histograms of positive and negatives along with threshold
criterion.
You need provide one or more development score file(s) for each experiment.
You need to provide one or more development score file(s) for each experiment.
You can also provide evaluation files along with dev files. If only dev scores
are provided, you must use flag `--no-evaluation`.
......@@ -189,7 +191,6 @@ def hist(ctx, scores, evaluation, **kwargs):
process = figure.Hist(ctx, scores, evaluation, load.split_files)
process.run()
@click.command()
@common_options.scores_argument(nargs=-1)
@common_options.titles_option()
......@@ -203,6 +204,9 @@ def hist(ctx, scores, evaluation, **kwargs):
@common_options.n_bins_option()
@common_options.lines_at_option()
@common_options.const_layout_option()
@common_options.figsize_option()
@common_options.style_option()
@common_options.const_layout_option()
@verbosity_option()
@click.pass_context
def evaluate(ctx, scores, evaluation, **kwargs):
......@@ -227,6 +231,11 @@ def evaluate(ctx, scores, evaluation, **kwargs):
Examples:
$ bob measure evaluate dev-scores
$ bob measure evaluate scores-dev1 scores-eval1 scores-dev2
scores-eval2
$ bob measure evaluate /path/to/sys-{1,2,3}/scores-{dev,eval}
$ bob measure evaluate -l metrics.txt -o my_plots.pdf dev-scores eval-scores
'''
# first time erase if existing file
......@@ -256,11 +265,10 @@ def evaluate(ctx, scores, evaluation, **kwargs):
if evaluation:
click.echo("Computing EPC...")
ctx.forward(epc) # use class defaults plot settings
ctx.forward(epc)
# the last one closes the file
ctx.meta['closef'] = True
click.echo("Computing score histograms...")
ctx.meta['criter'] = 'hter' # no criterion passed in evaluate
ctx.meta['criter'] = 'eer' # no criterion passed in evaluate
ctx.forward(hist)
click.echo("Evaluate successfully completed!")
click.echo("[plots] => %s" % (ctx.meta['output']))
'''Stores click common options for plots'''
import math
import pkg_resources # to make sure bob gets imported properly
import logging
import click
from click.types import INT, FLOAT, Choice, File
from click.types import INT, FLOAT
import matplotlib.pyplot as plt
from matplotlib.backends.backend_pdf import PdfPages
from bob.extension.scripts.click_helper import (verbosity_option, bool_option,
list_float_option)
from bob.extension.scripts.click_helper import (bool_option, list_float_option)
logger = logging.getLogger(__name__)
LOGGER = logging.getLogger(__name__)
def scores_argument(eval_mandatory=False, min_len=1, **kwargs):
"""Get the argument for scores, and add `dev-scores` and `eval-scores` in
......@@ -18,7 +16,6 @@ def scores_argument(eval_mandatory=False, min_len=1, **kwargs):
Parameters
----------
eval_mandatory :
If evaluation files are mandatory
min_len :
......@@ -27,7 +24,8 @@ def scores_argument(eval_mandatory=False, min_len=1, **kwargs):
Returns
-------
Click option
callable
A decorator to be used for adding score arguments for click commands
"""
def custom_scores_argument(func):
def callback(ctx, param, value):
......@@ -129,23 +127,10 @@ def lines_at_option(**kwargs):
'''Get option to draw const far line'''
return list_float_option(
name='lines-at', short_name='la',
desc='If given, draw a veritcal lines on ROC plots',
desc='If given, draw veritcal lines on ROC plots',
nitems=None, dflt=None, **kwargs
)
def axis_fontsize_option(dflt=8, **kwargs):
'''Get option for axis font size'''
def custom_axis_fontsize_option(func):
def callback(ctx, param, value):
value = abs(value)
ctx.meta['fontsize'] = value
return value
return click.option(
'-F', '--fontsize', type=click.INT, default=dflt, show_default=True,
help='Axis fontsize',
callback=callback, **kwargs)(func)
return custom_axis_fontsize_option
def x_rotation_option(dflt=0, **kwargs):
'''Get option for rotartion of the x axis lables'''
def custom_x_rotation_option(func):
......@@ -159,7 +144,6 @@ def x_rotation_option(dflt=0, **kwargs):
callback=callback, **kwargs)(func)
return custom_x_rotation_option
def cost_option(**kwargs):
'''Get option to get cost for FAR'''
def custom_cost_option(func):
......@@ -174,18 +158,6 @@ def cost_option(**kwargs):
callback=callback, **kwargs)(func)
return custom_cost_option
def n_sys_option(**kwargs):
'''Get the number of systems to be processed'''
def custom_n_sys_option(func):
def callback(ctx, param, value):
ctx.meta['n_sys'] = value
return value
return click.option(
'--n-sys', type=INT, default=1, show_default=True,
help='The number of systems to be processed',
callback=callback, is_eager=True , **kwargs)(func)
return custom_n_sys_option
def points_curve_option(**kwargs):
'''Get the number of points use to draw curves'''
def custom_points_curve_option(func):
......@@ -248,7 +220,7 @@ def output_plot_file_option(default_out='plots.pdf', **kwargs):
print the path of the file in the log'''
ctx.meta['output'] = value
ctx.meta['PdfPages'] = PdfPages(value)
logger.debug("Plots will be output in %s", value)
LOGGER.debug("Plots will be output in %s", value)
return value
return click.option(
'-o', '--output',
......@@ -264,7 +236,7 @@ def output_plot_metric_option(**kwargs):
''' Save ouput file and associated pdf in context list,
print the path of the file in the log'''
if value is not None:
logger.debug("Metrics will be output in %s", value)
LOGGER.debug("Metrics will be output in %s", value)
ctx.meta['log'] = value
return value
return click.option(
......@@ -279,7 +251,6 @@ def criterion_option(lcriteria=['eer', 'hter', 'far'], **kwargs):
Parameters
----------
lcriteria : :any:`list`
List of possible criteria
"""
......@@ -299,7 +270,6 @@ def criterion_option(lcriteria=['eer', 'hter', 'far'], **kwargs):
callback=callback, is_eager=True ,**kwargs)(func)
return custom_criterion_option
def far_option(**kwargs):
'''Get option to get far value'''
def custom_far_option(func):
......@@ -314,40 +284,6 @@ def far_option(**kwargs):
callback=callback, show_default=True,**kwargs)(func)
return custom_far_option
def rank_option(**kwargs):
'''Get option for rank parameter'''
def custom_rank_option(func):
def callback(ctx, param, value):
value = 1 if value < 0 else value
ctx.meta['rank'] = value
return value
return click.option(
'--rank', type=click.INT, default=1,
help='Given threshold for metrics computations',
callback=callback, show_default=True,**kwargs)(func)
return custom_rank_option
def label_option(name_option='x_label', **kwargs):
'''Get labels options based on the given name.
Parameters:
----------
name_option: str, optional
Name of the label option (e.g. x-lable, y1-label)
'''
def custom_label_option(func):
def callback(ctx, param, value):
''' Get and save labels list in the context list '''
ctx.meta[name_option.replace('-', '_')] = value if value is None else \
[int(i) for i in value.split(',')]
return value
return click.option(
'--' + name_option,
help='The id of figures which should have x_label separated by '
'comma. For example ``--%s 1,2,4``.' % name_option,
callback=callback, **kwargs)(func)
return custom_label_option
def figsize_option(**kwargs):
'''Get option for matplotlib figsize'''
def custom_figsize_option(func):
......
This diff is collapsed.
......@@ -16,11 +16,10 @@ NUM_NEG = 5000
NUM_POS = 5000
def gen_score_distr(mean_neg, mean_pos, sigma_neg=1, sigma_pos=1):
"""Generate scores from normal distributions
"""Generate scores from normal distributions
Parameters
----------
mean_neg : float
Mean for negative scores
mean_pos : float
......@@ -32,10 +31,9 @@ def gen_score_distr(mean_neg, mean_pos, sigma_neg=1, sigma_pos=1):
Returns
-------
neg_scores : array_like
neg_scores : :any:`list`
Negatives scores
pos_scores : array_like
pos_scores : :any:`list`
Positive scores
"""
mt = random.mt19937() # initialise the random number generator
......@@ -56,9 +54,9 @@ def write_scores_to_file(pos, neg, filename):
Parameters
----------
pos : array_like
pos : :py:class:`numpy.ndarray`
Scores for positive samples.
neg : array_like
neg : :py:class:`numpy.ndarray`
Scores for negative samples.
filename : str
The path to write the score to.
......
......@@ -7,8 +7,8 @@ from click.types import INT, FLOAT, Choice, File
@with_plugins(pkg_resources.iter_entry_points('bob.measure.cli'))
@click.group(chain=True)
@click.group()
def measure():
"""Entry for bob.measure commands."""
"""Generic performance evaluation commands."""
pass
......@@ -2,7 +2,6 @@
import numpy
import scipy.stats
import click
import bob.core
def remove_nan(scores):
......@@ -12,7 +11,6 @@ def remove_nan(scores):
Parameters
----------
scores :
:py:class:`numpy.ndarray` : array
......@@ -37,7 +35,6 @@ def get_fta(scores):
Parameters
----------
scores :
Tuple of (``positive``, ``negative``) :py:class:`numpy.ndarray`.
......@@ -61,7 +58,6 @@ def get_thres(criter, neg, pos, far=None):
Parameters
----------
criter :
Criterion (`eer` or `hter`)
neg : :py:class:`numpy.ndarray`:
......@@ -71,10 +67,8 @@ def get_thres(criter, neg, pos, far=None):
Returns
-------
:py:obj:`float`
threshold
"""
if criter == 'eer':
from . import eer_threshold
......@@ -84,13 +78,12 @@ def get_thres(criter, neg, pos, far=None):
return min_hter_threshold(neg, pos)
elif criter == 'far':
if far is None:
raise click.UsageError("FAR value must be provided through "
"``--far-value`` option.")
raise ValueError("FAR value must be provided through "
"``--far-value`` option.")
from . import far_threshold
return far_threshold(neg, pos, far)
else:
raise click.UsageError("Incorrect plotting criterion: ``%s``" % criter)
raise ValueError("Incorrect plotting criterion: ``%s``" % criter)
def get_colors(n):
"""get_colors
......@@ -98,13 +91,11 @@ def get_colors(n):
Parameters
----------
n : :obj:`int`
Number of colors to output
Returns
-------
:any:`list`
list of colors
"""
......
......@@ -127,3 +127,5 @@ Details
.. automodule:: bob.measure.utils
.. automodule:: bob.measure.script.figure
.. automodule:: bob.measure.script.commands
.. automodule:: bob.measure.script.gen
.. automodule:: bob.measure.script.common_options
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment