Beispiel #1
0
 def example_cpd(self, id_=0):
     kw = dict()
     if self.evidence_ttypes is None:
         kw['parents'] = ut.chr_range(id_, id_ + 1)[0]
     else:
         kw['parents'] = [
             tcpd.example_cpd(i)
             for i, tcpd in enumerate(self.evidence_ttypes)
         ]
     example_cpd = self.new_cpd(**kw)
     return example_cpd
Beispiel #2
0
 def example_cpd(self, id_=0):
     kw = dict()
     if self.evidence_ttypes is None:
         kw['parents'] = ut.chr_range(id_, id_ + 1)[0]
     else:
         kw['parents'] = [
             tcpd.example_cpd(i)
             for i, tcpd in enumerate(self.evidence_ttypes)
         ]
     example_cpd = self.new_cpd(**kw)
     return example_cpd
Beispiel #3
0
def vim_popup_menu():
    """ http://stackoverflow.com/questions/13537521/custom-popup-menu-in-vim """
    import vim
    import utool as ut
    vim.command('echohl Title')
    vim.command("echo 'Code fragments:'")
    vim.command("echohl None")
    options = ['foo', 'bar']
    id_list = ut.chr_range(len(options), base='1')
    for id_, opt in zip(id_list, options):
        vim.command("echo '%s. %s'" % (id_, opt))
    choice = chr(int(vim.eval('getchar()')))
    print('choice = %r' % (choice,))
    pass
Beispiel #4
0
def vim_popup_menu(options):
    """ http://stackoverflow.com/questions/13537521/custom-popup-menu-in-vim """
    import vim
    import utool as ut
    vim.command('echohl Title')
    vim.command("echo 'Code fragments:'")
    vim.command("echohl None")
    id_list = ut.chr_range(len(options), base='1')
    for id_, opt in zip(id_list, options):
        vim.command("echo '%s. %s'" % (id_, opt))
    vim.command("echo 'Enter the number of your choice '")
    choice = chr(int(vim.eval('getchar()')))
    print('choice = %r' % (choice,))
    try:
        chosen = options[int(choice) - 1]
    except TypeError:
        chosen = None
    print('chosen = %r' % (chosen,))
    return chosen
Beispiel #5
0
def test_avl_split(verbose=1):
    for num in range(0, 20):
        for index in range(num):
            if verbose:
                print('------')
                print('num = %r' % (num,))
                print('index = %r' % (index,))
            try:
                tree0 = EulerTourTree(ut.chr_range(num))
                tour = list(tree0)
                tree0._assert_nodes()
                if verbose >= 2:
                    tree0.print_tree()
                if verbose:
                    print('tree0 = %r' % (tree0,))
                node = tree0.get_node(index)
                if verbose:
                    print('node = %s' % (node,))
                part1, part2, bnode = avl_split(tree0.root, node)
                tree1 = EulerTourTree(root=part1)
                tree2 = EulerTourTree(root=part2)
                if verbose >= 2:
                    tree1.print_tree(), tree2.print_tree()
                if verbose:
                    print('tree1 = %r' % (tree1,))
                    print('tree2 = %r' % (tree2,))
                # Should correspond to a split in the tour list
                assert bnode.left is None, 'bnode must be split'
                assert bnode.right is None, 'bnode must be split'
                assert bnode.parent is None, 'bnode must be split'
                assert bnode is node, 'node must be same'
                ut.assert_eq(list(tree1), tour[:index])
                ut.assert_eq(list(tree2), tour[index + 1:])
                tree1._assert_nodes(), tree2._assert_nodes()
            except Exception:
                print('num = %r' % (num,))
                print('index = %r' % (index,))
                raise
Beispiel #6
0
def make_name_model(num_annots, num_names=None, verbose=True, mode=1):
    """
    Defines the general name model

    CommandLine:
        python -m wbia.algo.hots.bayes --exec-make_name_model --show

    Example:
        >>> # DISABLE_DOCTEST
        >>> from wbia.algo.hots.bayes import *  # NOQA
        >>> defaults = dict(num_annots=2, num_names=2, verbose=True, mode=2)
        >>> kw = ut.argparse_funckw(make_name_model, defaults)
        >>> model = make_name_model(**kw)
        >>> ut.quit_if_noshow()
        >>> show_model(model, show_prior=True)
        >>> ut.show_if_requested()
    """
    # annots = ut.chr_range(num_annots, base='a')
    mode = ut.get_argval('--mode', default=mode)
    annots = ut.chr_range(num_annots,
                          base=ut.get_argval('--base', default='a'))
    # The indexes of match CPDs will not change if another annotation is added
    upper_diag_idxs = ut.colwise_diag_idxs(num_annots, 2)
    if num_names is None:
        num_names = num_annots

    # -- Define CPD Templates
    def match_pmf(match_type, n1, n2):
        if n1 == n2:
            val = 1.0 if match_type == 'same' else 0.0
            # val = .999 if match_type == 'same' else 0.001
        elif n1 != n2:
            # val = 0.01 if match_type == 'same' else .99
            val = 0.0 if match_type == 'same' else 1.0
        return val

    def score_pmf(score_type, match_type):
        score_lookup = {
            'same': {
                'low': 0.1,
                'high': 0.9,
                'veryhigh': 0.9
            },
            'diff': {
                'low': 0.9,
                'high': 0.09,
                'veryhigh': 0.01
            }
            #'same': {'low': .1, 'high': .9},
            #'diff': {'low': .9, 'high': .1}
        }
        val = score_lookup[match_type][score_type]
        return val

    def score_pmf3(score_type, match_type, isdup='False'):
        score_lookup = {
            'False': {
                'same': {
                    'low': 0.1,
                    'high': 0.5,
                    'veryhigh': 0.4
                },
                'diff': {
                    'low': 0.9,
                    'high': 0.09,
                    'veryhigh': 0.01
                },
            },
            'True': {
                'same': {
                    'low': 0.01,
                    'high': 0.2,
                    'veryhigh': 0.79
                },
                'diff': {
                    'low': 0.4,
                    'high': 0.4,
                    'veryhigh': 0.2
                },
            },
        }
        val = score_lookup[isdup][match_type][score_type]
        return val

    def score_pmf2(score_type, n1, n2):
        score_lookup = {
            True: {
                'low': 0.1,
                'high': 0.4,
                'veryhigh': 0.5
            },
            False: {
                'low': 0.9,
                'high': 0.09,
                'veryhigh': 0.01
            },
        }
        val = score_lookup[n1 == n2][score_type]
        return val

    def dup_pmf(dupstate, match_type):
        lookup = {
            'same': {
                'True': 0.5,
                'False': 0.5
            },
            'diff': {
                'True': 0.0,
                'False': 1.0
            },
        }
        return lookup[match_type][dupstate]

    def check_pmf(n0, n1, match_type):
        pass

    def trimatch_pmf(match_ab, match_bc, match_ca):
        lookup = {
            'same': {
                'same': {
                    'same': 1,
                    'diff': 0
                },
                'diff': {
                    'same': 0,
                    'diff': 1
                },
            },
            'diff': {
                'same': {
                    'same': 0,
                    'diff': 1
                },
                'diff': {
                    'same': 0.5,
                    'diff': 0.5
                },
            },
        }
        return lookup[match_ca][match_bc][match_ab]

    name_cpd_t = pgm_ext.TemplateCPD('name', ('n', num_names),
                                     varpref='N',
                                     special_basis_pool=SPECIAL_BASIS_POOL)

    if mode == 1 or mode == 5:
        match_cpd_t = pgm_ext.TemplateCPD(
            'match',
            ['diff', 'same'],
            varpref='M',
            evidence_ttypes=[name_cpd_t, name_cpd_t],
            pmf_func=match_pmf,
        )

        if mode == 5:
            trimatch_cpd_t = pgm_ext.TemplateCPD(
                'tri_match',
                ['diff', 'same'],
                varpref='T',
                # evidence_ttypes=[match_cpd_t, match_cpd_t, match_cpd_t],
                evidence_ttypes=[match_cpd_t, match_cpd_t],
                pmf_func=trimatch_pmf,
            )

            score_cpd_t = pgm_ext.TemplateCPD(
                #'score', ['low', 'high', 'veryhigh'],
                'score',
                ['low', 'high'],
                varpref='S',
                evidence_ttypes=[match_cpd_t],
                pmf_func=score_pmf,
            )
        else:
            score_cpd_t = pgm_ext.TemplateCPD(
                #'score', ['low', 'high', 'veryhigh'],
                'score',
                ['low', 'high'],
                varpref='S',
                evidence_ttypes=[match_cpd_t],
                pmf_func=score_pmf,
            )

    elif mode == 2:
        name_cpd_t = pgm_ext.TemplateCPD('name', ('n', num_names),
                                         varpref='N',
                                         special_basis_pool=SPECIAL_BASIS_POOL)
        score_cpd_t = pgm_ext.TemplateCPD(
            #'score', ['low', 'high', 'veryhigh'],
            'score',
            ['low', 'high'],
            varpref='S',
            evidence_ttypes=[name_cpd_t, name_cpd_t],
            pmf_func=score_pmf2,
        )
    elif mode == 3 or mode == 4:
        match_cpd_t = pgm_ext.TemplateCPD(
            'match',
            ['diff', 'same'],
            varpref='M',
            evidence_ttypes=[name_cpd_t, name_cpd_t],
            pmf_func=match_pmf,
        )
        if mode == 3:
            dup_cpd_t = pgm_ext.TemplateCPD('dup', ['False', 'True'],
                                            varpref='D')
        else:
            dup_cpd_t = pgm_ext.TemplateCPD(
                'dup',
                ['False', 'True'],
                varpref='D',
                evidence_ttypes=[match_cpd_t],
                pmf_func=dup_pmf,
            )
        score_cpd_t = pgm_ext.TemplateCPD(
            'score',
            ['low', 'high', 'veryhigh'],
            varpref='S',
            evidence_ttypes=[match_cpd_t, dup_cpd_t],
            pmf_func=score_pmf3,
        )

    # Instanciate templates

    if mode == 1 or mode == 5:
        name_cpds = [name_cpd_t.new_cpd(parents=aid) for aid in annots]
        namepair_cpds = ut.list_unflat_take(name_cpds, upper_diag_idxs)
        match_cpds = [
            match_cpd_t.new_cpd(parents=cpds) for cpds in namepair_cpds
        ]
        score_cpds = [
            score_cpd_t.new_cpd(parents=cpds) for cpds in zip(match_cpds)
        ]
        if mode == 5:
            # triple_idxs = ut.colwise_diag_idxs(num_annots, 3)
            tid2_match = {cpd._template_id: cpd for cpd in match_cpds}
            trimatch_cpds = []
            # such hack
            for cpd in match_cpds:
                parents = []
                this_ = list(cpd._template_id)
                for aid in annots:
                    if aid in this_:
                        continue
                    for aid2 in this_:
                        key = aid2 + aid
                        if key not in tid2_match:
                            key = aid + aid2
                        parents += [tid2_match[key]]
                trimatch_cpds += [trimatch_cpd_t.new_cpd(parents=parents)]

            # score_cpds = [score_cpd_t.new_cpd(parents=cpds)
            #              for cpds in zip(trimatch_cpds)]

            cpd_list = name_cpds + score_cpds + match_cpds + trimatch_cpds
        else:
            cpd_list = name_cpds + score_cpds + match_cpds
    elif mode == 2:
        name_cpds = [name_cpd_t.new_cpd(parents=aid) for aid in annots]
        namepair_cpds = ut.list_unflat_take(name_cpds, upper_diag_idxs)
        score_cpds = [
            score_cpd_t.new_cpd(parents=cpds) for cpds in namepair_cpds
        ]
        cpd_list = name_cpds + score_cpds
    elif mode == 3 or mode == 4:
        name_cpds = [name_cpd_t.new_cpd(parents=aid) for aid in annots]
        namepair_cpds = ut.list_unflat_take(name_cpds, upper_diag_idxs)
        match_cpds = [
            match_cpd_t.new_cpd(parents=cpds) for cpds in namepair_cpds
        ]
        if mode == 3:
            dup_cpds = [
                dup_cpd_t.new_cpd(parents=''.join(map(str, aids)))
                for aids in ut.list_unflat_take(annots, upper_diag_idxs)
            ]
        else:
            dup_cpds = [
                dup_cpd_t.new_cpd(parents=[mcpds]) for mcpds in match_cpds
            ]
        score_cpds = [
            score_cpd_t.new_cpd(parents=([mcpds] + [dcpd]))
            for mcpds, dcpd in zip(match_cpds, dup_cpds)
        ]
        cpd_list = name_cpds + score_cpds + match_cpds + dup_cpds

    # logger.info('upper_diag_idxs = %r' % (upper_diag_idxs,))
    logger.info('score_cpds = %r' %
                (ut.list_getattr(score_cpds, 'variable'), ))
    # import sys
    # sys.exit(1)

    # Make Model
    model = pgm_ext.define_model(cpd_list)
    model.num_names = num_names

    if verbose:
        model.print_templates()
        # ut.colorprint('\n --- CPD Templates ---', 'blue')
        # for temp_cpd in templates:
        #    ut.colorprint(temp_cpd._cpdstr('psql'), 'cyan')
    # print_ascii_graph(model)
    return model
Beispiel #7
0
def name_model_mode1(num_annots, num_names=None, verbose=True):
    r"""
    spaghettii

    CommandLine:
        python -m wbia.algo.hots.bayes --exec-name_model_mode1 --show
        python -m wbia.algo.hots.bayes --exec-name_model_mode1
        python -m wbia.algo.hots.bayes --exec-name_model_mode1 --num-annots=3

    Example:
        >>> # DISABLE_DOCTEST
        >>> from wbia.algo.hots.bayes import *  # NOQA
        >>> defaults = dict(num_annots=2, num_names=2, verbose=True)
        >>> kw = ut.argparse_funckw(name_model_mode1, defaults)
        >>> model = name_model_mode1(**kw)
        >>> ut.quit_if_noshow()
        >>> show_model(model, show_prior=False, show_title=False)
        >>> ut.show_if_requested()

    Ignore:
        import nx2tikz
        logger.info(nx2tikz.dumps_tikz(model, layout='layered', use_label=True))
    """
    annots = ut.chr_range(num_annots,
                          base=ut.get_argval('--base', default='a'))
    # The indexes of match CPDs will not change if another annotation is added
    upper_diag_idxs = ut.colwise_diag_idxs(num_annots, 2)
    if num_names is None:
        num_names = num_annots

    # +--- Define CPD Templates ---

    # +-- Name Factor ---
    name_cpd_t = pgm_ext.TemplateCPD('name', ('n', num_names),
                                     varpref='N',
                                     special_basis_pool=SPECIAL_BASIS_POOL)
    name_cpds = [name_cpd_t.new_cpd(parents=aid) for aid in annots]

    # +-- Match Factor ---
    def match_pmf(match_type, n1, n2):
        return {
            True: {
                'same': 1.0,
                'diff': 0.0
            },
            False: {
                'same': 0.0,
                'diff': 1.0
            },
        }[n1 == n2][match_type]

    match_cpd_t = pgm_ext.TemplateCPD(
        'match',
        ['diff', 'same'],
        varpref='M',
        evidence_ttypes=[name_cpd_t, name_cpd_t],
        pmf_func=match_pmf,
    )
    namepair_cpds = ut.list_unflat_take(name_cpds, upper_diag_idxs)
    match_cpds = [match_cpd_t.new_cpd(parents=cpds) for cpds in namepair_cpds]

    # +-- Score Factor ---
    def score_pmf(score_type, match_type):
        score_lookup = {
            'same': {
                'low': 0.1,
                'high': 0.9,
                'veryhigh': 0.9
            },
            'diff': {
                'low': 0.9,
                'high': 0.09,
                'veryhigh': 0.01
            },
        }
        val = score_lookup[match_type][score_type]
        return val

    score_cpd_t = pgm_ext.TemplateCPD(
        'score',
        ['low', 'high'],
        varpref='S',
        evidence_ttypes=[match_cpd_t],
        pmf_func=score_pmf,
    )
    score_cpds = [
        score_cpd_t.new_cpd(parents=cpds) for cpds in zip(match_cpds)
    ]

    # L___ End CPD Definitions ___

    cpd_list = name_cpds + score_cpds + match_cpds
    logger.info('score_cpds = %r' %
                (ut.list_getattr(score_cpds, 'variable'), ))

    # Make Model
    model = pgm_ext.define_model(cpd_list)
    model.num_names = num_names

    if verbose:
        model.print_templates()
    return model
Beispiel #8
0
def name_model_mode5(num_annots, num_names=None, verbose=True, mode=1):
    mode = ut.get_argval('--mode', default=mode)
    annots = ut.chr_range(num_annots,
                          base=ut.get_argval('--base', default='a'))
    # The indexes of match CPDs will not change if another annotation is added
    upper_diag_idxs = ut.colwise_diag_idxs(num_annots, 2)
    if num_names is None:
        num_names = num_annots

    # -- Define CPD Templates

    name_cpd_t = pgm_ext.TemplateCPD('name', ('n', num_names),
                                     varpref='N',
                                     special_basis_pool=SPECIAL_BASIS_POOL)
    name_cpds = [name_cpd_t.new_cpd(parents=aid) for aid in annots]

    def match_pmf(match_type, n1, n2):
        return {
            True: {
                'same': 1.0,
                'diff': 0.0
            },
            False: {
                'same': 0.0,
                'diff': 1.0
            },
        }[n1 == n2][match_type]

    match_cpd_t = pgm_ext.TemplateCPD(
        'match',
        ['diff', 'same'],
        varpref='M',
        evidence_ttypes=[name_cpd_t, name_cpd_t],
        pmf_func=match_pmf,
    )
    namepair_cpds = ut.list_unflat_take(name_cpds, upper_diag_idxs)
    match_cpds = [match_cpd_t.new_cpd(parents=cpds) for cpds in namepair_cpds]

    def trimatch_pmf(match_ab, match_bc, match_ca):
        lookup = {
            'same': {
                'same': {
                    'same': 1,
                    'diff': 0
                },
                'diff': {
                    'same': 0,
                    'diff': 1
                },
            },
            'diff': {
                'same': {
                    'same': 0,
                    'diff': 1
                },
                'diff': {
                    'same': 0.5,
                    'diff': 0.5
                },
            },
        }
        return lookup[match_ca][match_bc][match_ab]

    trimatch_cpd_t = pgm_ext.TemplateCPD(
        'tri_match',
        ['diff', 'same'],
        varpref='T',
        evidence_ttypes=[match_cpd_t, match_cpd_t],
        pmf_func=trimatch_pmf,
    )
    # triple_idxs = ut.colwise_diag_idxs(num_annots, 3)
    tid2_match = {cpd._template_id: cpd for cpd in match_cpds}
    trimatch_cpds = []
    # such hack
    for cpd in match_cpds:
        parents = []
        this_ = list(cpd._template_id)
        for aid in annots:
            if aid in this_:
                continue
            for aid2 in this_:
                key = aid2 + aid
                if key not in tid2_match:
                    key = aid + aid2
                parents += [tid2_match[key]]
        trimatch_cpds += [trimatch_cpd_t.new_cpd(parents=parents)]

    def score_pmf(score_type, match_type):
        score_lookup = {
            'same': {
                'low': 0.1,
                'high': 0.9,
                'veryhigh': 0.9
            },
            'diff': {
                'low': 0.9,
                'high': 0.09,
                'veryhigh': 0.01
            },
        }
        val = score_lookup[match_type][score_type]
        return val

    score_cpd_t = pgm_ext.TemplateCPD(
        'score',
        ['low', 'high'],
        varpref='S',
        evidence_ttypes=[match_cpd_t],
        pmf_func=score_pmf,
    )
    score_cpds = [
        score_cpd_t.new_cpd(parents=cpds) for cpds in zip(match_cpds)
    ]

    # score_cpds = [score_cpd_t.new_cpd(parents=cpds)
    #              for cpds in zip(trimatch_cpds)]

    cpd_list = name_cpds + score_cpds + match_cpds + trimatch_cpds
    logger.info('score_cpds = %r' %
                (ut.list_getattr(score_cpds, 'variable'), ))

    # Make Model
    model = pgm_ext.define_model(cpd_list)
    model.num_names = num_names

    if verbose:
        model.print_templates()
    return model
Beispiel #9
0
def make_name_model(num_annots, num_names=None, verbose=True, mode=1,
                    num_scores=2, p_score_given_same=None,
                    hack_score_only=False, score_basis=None,
                    special_names=None):
    r"""
    CommandLine:
        python -m ibeis.algo.hots.bayes --exec-make_name_model --show
        python -m ibeis.algo.hots.bayes --exec-make_name_model
        python -m ibeis.algo.hots.bayes --exec-make_name_model --num-annots=3

    Example:
        >>> # DISABLE_DOCTEST
        >>> from ibeis.algo.hots.bayes import *  # NOQA
        >>> defaults = dict(num_annots=2, num_names=2, verbose=True)
        >>> modeltype = ut.get_argval('--modeltype', default='bayes')
        >>> kw = ut.argparse_funckw(make_name_model, defaults)
        >>> model = make_name_model(**kw)
        >>> ut.quit_if_noshow()
        >>> model.show_model(show_prior=False, show_title=False, modeltype=modeltype)
        >>> ut.show_if_requested()
    """
    if special_names is None:
        special_names = SPECIAL_BASIS_POOL

    assert mode == 1, 'only can do mode 1'
    base = ut.get_argval('--base', type_=str, default='a')
    annots = ut.chr_range(num_annots, base=base)
    # The indexes of match CPDs will not change if another annotation is added
    upper_diag_idxs = ut.colwise_diag_idxs(num_annots, 2)
    if hack_score_only:
        upper_diag_idxs = upper_diag_idxs[-hack_score_only:]

    if num_names is None:
        num_names = num_annots

    # +--- Define CPD Templates and Instantiation ---
    cpd_list = []

    # Name Factor
    name_cpd_t = pgm_ext.TemplateCPD(
        'name', ('n', num_names),
        special_basis_pool=special_names)
    name_cpds = [name_cpd_t.new_cpd(parents=aid) for aid in annots]
    #name_cpds = [name_cpd_t.new_cpd(parents=aid, constrain_state=count)
    #             for count, aid in enumerate(annots, start=1)]
    cpd_list.extend(name_cpds)

    # Match Factor
    def match_pmf(match_type, n1, n2):
        return {
            True: {'same': 1.0, 'diff': 0.0},
            False: {'same': 0.0, 'diff': 1.0},
        }[n1 == n2][match_type]
    match_states = ['diff', 'same']
    match_cpd_t = pgm_ext.TemplateCPD(
        'match', match_states,
        evidence_ttypes=[name_cpd_t, name_cpd_t], pmf_func=match_pmf)
    namepair_cpds = ut.list_unflat_take(name_cpds, upper_diag_idxs)
    match_cpds = [match_cpd_t.new_cpd(parents=cpds)
                  for cpds in namepair_cpds]
    cpd_list.extend(match_cpds)

    # Score Factor
    score_states = list(range(num_scores))
    if score_basis is not None:
        score_states = ['%.2f' % (s,) for s in score_basis]
    if p_score_given_same is None:
        tmp = np.arange(num_scores + 1)[1:]
        tmp = np.cumsum(tmp)
        tmp = (tmp / tmp.sum())
        p_score_given_same = tmp
    def score_pmf(score_type, match_type):
        if isinstance(score_type, six.string_types):
            score_type = score_states.index(score_type)
        if match_type == 'same':
            return p_score_given_same[score_type]
        else:
            return p_score_given_same[-(score_type + 1)]
    score_cpd_t = pgm_ext.TemplateCPD(
        'score', score_states,
        evidence_ttypes=[match_cpd_t], pmf_func=score_pmf)
    score_cpds = [score_cpd_t.new_cpd(parents=cpds)
                  for cpds in zip(match_cpds)]
    cpd_list.extend(score_cpds)

    with_humans = False
    if with_humans:
        human_states = ['diff', 'same']
        human_cpd_t = pgm_ext.TemplateCPD(
            'human', human_states,
            evidence_ttypes=[match_cpd_t], pmf_func=[[.9, .1], [.1, .9]])
        human_cpds = [human_cpd_t.new_cpd(parents=cpds)
                      for cpds in zip(match_cpds)]
        cpd_list.extend(human_cpds)

    with_rank = False  # Rank depends on dependant scores
    if with_rank:
        rank_states = ['0', '1', '2', '3']
        rank_cpd_t = pgm_ext.TemplateCPD(
            'rank', rank_states,
            evidence_ttypes=[match_cpd_t], pmf_func=None)
        rank_cpds = [rank_cpd_t.new_cpd(parents=cpds)
                      for cpds in zip(match_cpds)]
        cpd_list.extend(rank_cpds)

    # L___ End CPD Definitions ___

    print('score_cpds = %r' % (ut.list_getattr(score_cpds, 'variable'),))

    # Make Model
    model = pgm_ext.define_model(cpd_list)
    model.num_names = num_names

    if verbose:
        model.print_templates(ignore_ttypes=['match'])
    return model
Beispiel #10
0
def make_name_model(
    num_annots,
    num_names=None,
    verbose=True,
    mode=1,
    num_scores=2,
    p_score_given_same=None,
    hack_score_only=False,
    score_basis=None,
    special_names=None,
):
    r"""
    CommandLine:
        python -m wbia.algo.hots.bayes --exec-make_name_model --no-cnn
        python -m wbia.algo.hots.bayes --exec-make_name_model --show --no-cnn
        python -m wbia.algo.hots.bayes --exec-make_name_model --num-annots=3

    Example:
        >>> # DISABLE_DOCTEST
        >>> from wbia.algo.hots.bayes import *  # NOQA
        >>> defaults = dict(num_annots=2, num_names=2, verbose=True)
        >>> modeltype = ut.get_argval('--modeltype', default='bayes')
        >>> kw = ut.argparse_funckw(make_name_model, defaults)
        >>> model = make_name_model(**kw)
        >>> ut.quit_if_noshow()
        >>> model.show_model(show_prior=False, show_title=False, modeltype=modeltype)
        >>> ut.show_if_requested()
    """
    if special_names is None:
        special_names = SPECIAL_BASIS_POOL

    assert mode == 1, 'only can do mode 1'
    base = ut.get_argval('--base', type_=str, default='a')
    annots = ut.chr_range(num_annots, base=base)
    # The indexes of match CPDs will not change if another annotation is added
    upper_diag_idxs = ut.colwise_diag_idxs(num_annots, 2)
    if hack_score_only:
        upper_diag_idxs = upper_diag_idxs[-hack_score_only:]

    if num_names is None:
        num_names = num_annots

    # +--- Define CPD Templates and Instantiation ---
    cpd_list = []

    # Name Factor
    name_cpd_t = pgm_ext.TemplateCPD(NAME_TTYPE, ('n', num_names),
                                     special_basis_pool=special_names)
    name_cpds = [name_cpd_t.new_cpd(parents=aid) for aid in annots]
    # name_cpds = [name_cpd_t.new_cpd(parents=aid, constrain_state=count)
    #             for count, aid in enumerate(annots, start=1)]
    cpd_list.extend(name_cpds)

    # Match Factor
    def match_pmf(match_type, n1, n2):
        return {
            True: {
                'same': 1.0,
                'diff': 0.0
            },
            False: {
                'same': 0.0,
                'diff': 1.0
            }
        }[n1 == n2][match_type]

    match_states = ['diff', 'same']
    match_cpd_t = pgm_ext.TemplateCPD(
        MATCH_TTYPE,
        match_states,
        evidence_ttypes=[name_cpd_t, name_cpd_t],
        pmf_func=match_pmf,
    )
    # match_cpd_t.varpref = 'S'
    namepair_cpds = ut.unflat_take(name_cpds, upper_diag_idxs)
    match_cpds = [match_cpd_t.new_cpd(parents=cpds) for cpds in namepair_cpds]
    cpd_list.extend(match_cpds)

    # Score Factor
    score_states = list(range(num_scores))
    if score_basis is not None:
        score_states = ['%.2f' % (s, ) for s in score_basis]
    if p_score_given_same is None:
        tmp = np.arange(num_scores + 1)[1:]
        tmp = np.cumsum(tmp)
        tmp = tmp / tmp.sum()
        p_score_given_same = tmp

    def score_pmf(score_type, match_type):
        if isinstance(score_type, six.string_types):
            score_type = score_states.index(score_type)
        if match_type == 'same':
            return p_score_given_same[score_type]
        else:
            return p_score_given_same[-(score_type + 1)]

    score_cpd_t = pgm_ext.TemplateCPD(SCORE_TTYPE,
                                      score_states,
                                      evidence_ttypes=[match_cpd_t],
                                      pmf_func=score_pmf)
    # match_cpd_t.varpref = 'P'
    score_cpds = [
        score_cpd_t.new_cpd(parents=cpds) for cpds in zip(match_cpds)
    ]
    cpd_list.extend(score_cpds)

    with_humans = False
    if with_humans:
        human_states = ['diff', 'same']
        human_cpd_t = pgm_ext.TemplateCPD(
            'human',
            human_states,
            evidence_ttypes=[match_cpd_t],
            pmf_func=[[0.9, 0.1], [0.1, 0.9]],
        )
        human_cpds = [
            human_cpd_t.new_cpd(parents=cpds) for cpds in zip(match_cpds)
        ]
        cpd_list.extend(human_cpds)

    with_rank = False  # Rank depends on dependant scores
    if with_rank:
        rank_states = ['0', '1', '2', '3']
        rank_cpd_t = pgm_ext.TemplateCPD('rank',
                                         rank_states,
                                         evidence_ttypes=[match_cpd_t],
                                         pmf_func=None)
        rank_cpds = [
            rank_cpd_t.new_cpd(parents=cpds) for cpds in zip(match_cpds)
        ]
        cpd_list.extend(rank_cpds)

    # L___ End CPD Definitions ___

    logger.info('score_cpds = %r' %
                (ut.list_getattr(score_cpds, 'variable'), ))

    # Make Model
    model = pgm_ext.define_model(cpd_list)
    model.num_names = num_names

    if verbose:
        model.print_templates(ignore_ttypes=[MATCH_TTYPE])
    return model