PyMC的定制先锋

时间:2014-04-21 13:18:04

标签: python statsmodels pymc

假设我想在PyMC中的两个变量ab上添加自定义优先级,例如:

p(a,b)∝(a+b)^(−5/2)

(对于此前选择背后的动机,请参阅this answer

这可以在PyMC中完成吗?如果是这样的话?

例如,我想在下面的模型中ab上定义此类优先顺序。

import pymc as pm

# ...
# Code that defines the prior: p(a,b)∝(a+b)^(−5/2)
# ...

theta   = pm.Beta("prior", alpha=a, beta=b)

# Binomials that share a common prior
bins = dict()
for i in xrange(N_cities):
    bins[i] = pm.Binomial('bin_{}'.format(i), p=theta,n=N_trials[i],  value=N_yes[i], observed=True)

mcmc = pm.MCMC([bins, ps])

更新

按照John Salvatier的建议,我尝试以下(注意我在PyMC2中,虽然我很乐意切换到PyMC3),但我的问题是:

  1. 我应该导入什么才能正确地继承Continuous
  2. 在PyMC2中,我还需要坚持使用Theano表示法吗?
  3. 最后,我怎样才能告诉Beta alpha beta这个多变量分布中:Parameters: None :Support: 2 positive floats (parameters to a Beta distribution) """ def __init__(self, mu, tau, *args, **kwargs): super(CustomPrior, self).__init__(*args, **kwargs) def logp(self, a,b): return np.log(math.power(a+b),-5./2) 和{{1}}之前的分布?

    import pymc.Multivariate.Continuous

    class CustomPrior(连续):     """     P(A,B)α(A + B)^( - 5/2)

    {{1}}

2 个答案:

答案 0 :(得分:4)

烨!这很有可能,事实上非常简单。

如果您在PyMC 2中,请查看documentation on the creation of stochastic variables

@pymc.stochastic(dtype=int)
def switchpoint(value=1900, t_l=1851, t_h=1962):
    """The switchpoint for the rate of disaster occurrence."""
    if value > t_h or value < t_l:
        # Invalid values
        return -np.inf
    else:
        # Uniform log-likelihood
        return -np.log(t_h - t_l + 1)

如果您在PyMC 3中,请查看multivariate.py。请记住,传递给 init 和logp的值是所有theano变量,而不是numpy数组。这足以让你入门吗?

例如,这是多变量正态分布

class MvNormal(Continuous):
    """
    Multivariate normal

    :Parameters:
        mu : vector of means
        tau : precision matrix

    .. math::
        f(x \mid \pi, T) = \frac{|T|^{1/2}}{(2\pi)^{1/2}} \exp\left\{ -\frac{1}{2} (x-\mu)^{\prime}T(x-\mu) \right\}

    :Support:
        2 array of floats
    """
    def __init__(self, mu, tau, *args, **kwargs):
        super(MvNormal, self).__init__(*args, **kwargs)
        self.mean = self.median = self.mode = self.mu = mu
        self.tau = tau

    def logp(self, value):
        mu = self.mu
        tau = self.tau

        delta = value - mu
        k = tau.shape[0]

        return 1/2. * (-k * log(2*pi) + log(det(tau)) - dot(delta.T, dot(tau, delta)))

答案 1 :(得分:3)

在PyMC2中,诀窍是将ab参数放在一起:

# Code that defines the prior: p(a,b)∝(a+b)^(−5/2)
@pm.stochastic
def ab(power=-2.5, value=[1,1]):
    if np.any(value <= 0):
        return -np.Inf
    return power * np.log(value[0]+value[1])

a = ab[0]
b = ab[1]

This notebook有一个完整的例子。