Пример #1
0
def default_prior(model_desc_pre):
    assert type(model_desc_pre) == ModelDescPre
    family = model_desc_pre.response.family
    assert type(family) == Family
    assert family.link is not None
    assert type(model_desc_pre.population) == PopulationPre
    assert type(model_desc_pre.groups) == list
    assert all(type(gm) == GroupPre for gm in model_desc_pre.groups)
    b_children = [leaf(name) for name in model_desc_pre.population.coefs]
    cor_children = [leaf(cols2str(group.columns)) for group in model_desc_pre.groups if group.corr]
    sd_children = [Node(cols2str(gm.columns), None, False, [], [leaf(name) for name in gm.coefs]) for gm in
                   model_desc_pre.groups]

    def mk_resp_prior_edit(param_name):
        prior = get_response_prior(family.name, param_name)
        if prior is not None:
            return Prior(('resp', param_name), prior)

    resp_children = [leaf(p.name, mk_resp_prior_edit(p.name), [chk_support(p.type)])
                     for p in model_desc_pre.response.nonlocparams]
    return Node('root', None, False, [], [
        Node('b', Prior(('b',), Cauchy(0., 1.)), False, [chk_support(Type['Real']())], b_children),
        Node('sd', Prior(('sd',), HalfCauchy(3.)), False, [chk_support(Type['PosReal']())], sd_children),
        Node('cor', Prior(('cor',), LKJ(1.)), False, [chk_lkj], cor_children),
        Node('resp', None, False, [], resp_children)])
Пример #2
0
    # Prior on coef of an interaction.
    ('y ~ x1:x2',
     [Categorical('x1', list('ab')),
      Categorical('x2', list('cd'))
      ], {}, Normal, [Prior(('b', 'x1[b]:x2[c]'),
                            Normal(0., 100.))], [('b_0', 'Cauchy', {}),
                                                 ('b_1', 'Normal', {
                                                     'loc': 0.,
                                                     'scale': 100.
                                                 }), ('b_2', 'Cauchy', {}),
                                                 ('sigma', 'HalfCauchy', {})]),

    # Prior on group level `sd` choice.
    ('y ~ 1 + x2 + x3 | x1', [Categorical('x1', list('ab'))], {}, Normal,
     [Prior(('sd', 'x1', 'intercept'),
            HalfCauchy(4.))], [('sigma', 'HalfCauchy', {}),
                               ('sd_0_0', 'HalfCauchy', {
                                   'scale': 4.
                               }), ('sd_0_1', 'HalfCauchy', {}),
                               ('z_0', 'Normal', {}), ('L_0', 'LKJ', {})]),
    ('y ~ 1 + x2 + x3 || x1', [Categorical('x1', list('ab'))], {}, Normal,
     [Prior(('sd', 'x1', 'intercept'),
            HalfNormal(4.))], [('sigma', 'HalfCauchy', {}),
                               ('sd_0_0', 'HalfNormal', {
                                   'scale': 4.
                               }), ('sd_0_1', 'HalfCauchy', {}),
                               ('z_0', 'Normal', {})]),
    ('y ~ 1 + x || a:b',
     [Categorical('a', ['a1', 'a2']),
      Categorical('b', ['b1', 'b2'])], {}, Normal,
     [Prior(('sd', 'a:b', 'intercept'),
Пример #3
0
from brmp.utils import join

# `is_param` indicates whether a node corresponds to a parameter in
# the model. (Nodes without this flag set exist only to add structure
# to the parameters.) This infomation is used when extracting
# information from the tree.
Node = namedtuple('Node', 'name prior_edit is_param checks children')


def leaf(name, prior_edit=None, checks=[]):
    return Node(name, prior_edit, True, checks, [])


RESPONSE_PRIORS = {
    'Normal': {
        'sigma': HalfCauchy(3.)
    },
}


def get_response_prior(family, parameter):
    if family in RESPONSE_PRIORS:
        return RESPONSE_PRIORS[family][parameter]


# This is similar to brms `set_prior`. (e.g. `set_prior('<prior>',
# coef='x1')` is similar to `Prior(['x1'], '<prior>)`.) By specifying
# paths (rather than class/group/coef) we're diverging from brms, but
# the hope is that a brms-like interface can be put in front of this.

Prior = namedtuple('Prior', 'path prior')