gen.py 2.93 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16
"""Generate random scores.
"""
import os
import logging
import numpy
import click
from click.types import FLOAT
from bob.extension.scripts.click_helper import verbosity_option
from bob.core import random
from bob.io.base import create_directories_safe

logger = logging.getLogger(__name__)

NUM_NEG = 5000
NUM_POS = 5000

17

18
def gen_score_distr(mean_neg, mean_pos, sigma_neg=1, sigma_pos=1):
19
    """Generate scores from normal distributions
20 21 22 23 24 25 26 27 28 29 30 31 32 33

    Parameters
    ----------
    mean_neg : float
        Mean for negative scores
    mean_pos : float
        Mean for positive scores
    sigma_neg : float
        STDev for negative scores
    sigma_pos : float
        STDev for positive scores

    Returns
    -------
34
    neg_scores : :any:`list`
35
        Negatives scores
36
    pos_scores : :any:`list`
37 38 39 40 41 42 43 44 45 46 47 48 49
        Positive scores
    """
    mt = random.mt19937()  # initialise the random number generator

    neg_generator = random.normal(numpy.float32, mean_neg, sigma_neg)
    pos_generator = random.normal(numpy.float32, mean_pos, sigma_pos)

    neg_scores = [neg_generator(mt) for _ in range(NUM_NEG)]
    pos_scores = [pos_generator(mt) for _ in range(NUM_NEG)]

    return neg_scores, pos_scores


50
def write_scores_to_file(neg, pos, filename):
51 52 53 54 55 56
    """Writes score distributions into 2-column score files. For the format of
    the 2-column score files, please refer to Bob's documentation. See
    :py:func:`bob.measure.load.split`.

    Parameters
    ----------
57
    neg : :py:class:`numpy.ndarray`
58
        Scores for negative samples.
59 60
    pos : :py:class:`numpy.ndarray`
        Scores for positive samples.
61 62 63 64 65 66 67 68 69 70 71 72 73 74
    filename : str
        The path to write the score to.
    """
    create_directories_safe(os.path.dirname(filename))
    mt = random.mt19937()
    nan_dist = random.uniform(numpy.float32, 0, 1)
    with open(filename, 'wt') as f:
        for i in pos:
            text = '1 %f\n' % i if nan_dist(mt) > 0.01 else '1 nan\n'
            f.write(text)
        for i in neg:
            text = '-1 %f\n' % i if nan_dist(mt) > 0.01 else '1 nan\n'
            f.write(text)

75

76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95
@click.command()
@click.argument('outdir')
@click.option('--mean-neg', default=-1, type=FLOAT, show_default=True)
@click.option('--mean-pos', default=1, type=FLOAT, show_default=True)
@verbosity_option()
def gen(outdir, mean_neg, mean_pos):
    """Generate random scores.
    Generates random scores for negative and positive scores, whatever they
    could be. The
    scores are generated using Gaussian distribution whose mean is an input
    parameter. The generated scores can be used as hypothetical datasets.
    """
    # Generate the data
    neg_dev, pos_dev = gen_score_distr(mean_neg, mean_pos)
    neg_eval, pos_eval = gen_score_distr(mean_neg, mean_pos)

    # Write the data into files
    write_scores_to_file(neg_dev, pos_dev,
                         os.path.join(outdir, 'scores-dev'))
    write_scores_to_file(neg_eval, pos_eval,
96
                         os.path.join(outdir, 'scores-eval'))