3

PyMC3 でカスタム プライアを定義できるかどうか (およびその方法) を知りたいです。ここから、PyMC2 では (ソース コードを変更する必要なく) 比較的簡単に実行できるように見えますが、PyMC3 ではそれほど簡単ではありません (または、私は何かを理解していません)。BUGS に実装されている本「Doing Bayesian Data Analysis」から前もって複製しようとしています。

model {
# Likelihood. Each flip is Bernoulli.
for ( i in 1 : N1 ) { y1[i]  ̃ dbern( theta1 ) }
for ( i in 1 : N2 ) { y2[i]  ̃ dbern( theta2 ) }
# Prior. Curved scallo not ps!
x  ̃ dunif(0,1)
y  ̃ dunif(0,1)
N <- 4
xt <- sin( 2*3.141593*N * x ) / (2*3.141593*N) + x
yt <- 3 * y + (1/3)
xtt <- pow( xt , yt )
theta1 <- xtt
theta2 <- y
}

事前確率はあまり意味がありません。カスタム事前確率の定義方法と BUGS の汎用性の例にすぎません。

上記のカスタム プライアを実装する私の試みは次のとおりです。

from __future__ import division
import numpy as np
import pymc as pm
from pymc import Continuous
from theano.tensor import sin, log

# Generate the data
y1 = np.array([1, 1, 1, 1, 1, 0, 0])  # 5 heads and 2 tails
y2 = np.array([1, 1, 0, 0, 0, 0, 0])  # 2 heads and 5 tails

class Custom_prior(Continuous): 
"""
custom prior
"""
    def __init__(self, y, *args, **kwargs):
        super(Custom_prior, self).__init__(*args, **kwargs)
        self.y = y
        self.N = 4
        self.mean = 0.625  # FIXME
    def logp(self, value):
        N = self.N
        y = self.y
        return -log((sin(2*3.141593*N * value)
                     / (2*3.141593*N) + value)**(3 * y + (1/3)))

with pm.Model() as model:
    theta2 = pm.Uniform('theta2', 0, 1)  # prior
    theta1 = Custom_prior('theta1', theta2)  # prior
    # define the likelihood
    y1 = pm.Bernoulli('y1', p=theta1, observed=y1)
    y2 = pm.Bernoulli('y2', p=theta2, observed=y2)
    # Generate a MCMC chain
    start = pm.find_MAP()  # Find starting value by optimization
    trace = pm.sample(5000, pm.NUTS(), progressbar=False)

編集

chris-fonnesbeckの回答に従う

次のようなものが必要だと思います:

with pm.Model() as model:
    theta2 = pm.Uniform('theta2', 0, 1)  # prior
    N = 4
    theta1 = pm.DensityDist('theta1', lambda value: -log((sin(2*3.141593*N * value)
                       / (2*3.141593*N) + value)**(3 * theta2 + (1/3))))
    # define the likelihood
    y1 = pm.Bernoulli('y1', p=theta1, observed=y1)
    y2 = pm.Bernoulli('y2', p=theta2, observed=y2)

    # Generate a MCMC chain
    start = pm.find_MAP()  # Find starting value by optimization
    trace = pm.sample(10000, pm.NUTS(), progressbar=False) # Use NUTS sampling

唯一の問題は、theta1 と theta2 のすべての事後サンプルで同じ値が得られることです。カスタムの事前確率または事前確率と尤度の組み合わせに問題があると思います。カスタム事前分布の成功した定義は、この例で見つけることができます

4

1 に答える 1

4

完全な BUGS モデルを投稿できますか? 上記では、事前定義の定義ではなく、x と y の事前確率の後の一連の BUGS の決定論的変換のように見えます。

ただし、上記が必要なものであると仮定すると、次のlogpように PyMC でより簡単に実装できます。

def logp(value, y):
    N  = 4
    return -log((sin(2*3.141593*N * value)
                 / (2*3.141593*N) + value)**(3 * y + (1/3)))

theta1 = pm.DensityDist('theta1', logp, value, y=theta2)
于 2014-07-14T14:52:40.340 に答える