Aunque no es estrictamente de "lápiz y papel" me imagino que usted está planeando este código en algún lenguaje, así que voy a escribir un ejemplo en el código de python, pero esperemos que esta escrito de tal forma que he de sacrificar la eficiencia y la limpieza del código a cambio de algo que es fácil de seguir y traducir a un idioma de su elección - esto es no un buen código, pero espero que sea legible el código!
Así que primero básico de las importaciones, especificando la previa de las distribuciones y sus hyperparameters así como la carga de los datos y la especificación de la log-verosimilitud. En este bloque de código que nos
- Especificar la función de densidad de probabilidad para la previa
- Carga los datos de la muestra
- Especificar el modelo loglikelihood
import numpy as np
from scipy.stats import multivariate_normal, wishart
def mu_prior_logpdf(m):
m0 = np.zeros(2)
C0 = np.diag(np.ones(2))
return multivariate_normal.logpdf(m, mean=m0, cov=C0)
def S_prior_logpdf(S):
df0 = 2
V0 = np.diag(np.ones(2))
return wishart.logpdf(S, df=df0, scale=V0)
nData = 3
X = np.array([[4, 5], [3, 3], [4, 2] ])
def loglik(X, m, S):
ll = 0.
for n in range(nData):
ll += multivariate_normal.logpdf( X[n, ], mean=m, cov=S )
return ll
Paso 2: Especificar la propuesta de distribución de
Hay varias opciones en este punto con respecto a lo algoritmo MCMC para elegir, en particular, hay buenas razones para el uso de muestreo de Gibbs - sin embargo , porque usted quiere una manera bastante general método vamos a demostrar una Metropolis-Hastings algoritmo MCMC que no requiere ningún conocimiento especial de las distribuciones condicionales.
Recordar para MH-MCMC necesitamos especificar una propuesta de distribución de q(θ∗|θ(n)), lo que da la distribución condicional de una nueva muestra θ∗ condicional en el valor actual de θ(n).
Ahora algunos pseudo-código para la propuesta de las distribuciones, de nuevo debe ser claro cómo modificar todo esto, en este ejemplo en particular la propuesta de q(μ∗|μ(n)) es administrado por un paseo aleatorio centra en el valor actual. Mientras que la propuesta de la covarianza es sólo una base independiente sampler q(Σ∗|Σ(n))=q(Σ∗), esto es, probablemente, para mostrar la convergencia pobres y muestreo de las propiedades, pero de nuevo esto es sólo para demostrar que el conjunto básico de seguridad
scale = 0.1
mpropCov = np.array([[ scale*scale, 0.], [0., scale*scale]])
def mu_proposal_rvs(mcur, size=1):
d = np.random.normal(size=2, scale=scale)
return mcur + d
def mu_proposal_logpdf(mnew, mcur):
return multivariate_normal.logpdf(mnew, mean=mcur, cov=mpropCov)
def S_proposal_rvs(scur, size=1):
return wishart.rvs(df=2, scale=np.diag(np.ones(2)))
def S_proposal_logpdf(Snew, Scur):
return wishart.logpdf(Snew, df=2, scale=np.diag(np.ones(2)))
Paso 3: Solo MCMC paso
Y ahora, un solo MH paso para que sus datos pueden proceder de la siguiente manera; dibujar una variable aleatoria a partir de la propuesta y, a continuación, acepta con una probabilidad de
Un(θ∗,θ(n))=min(1,p(X|θ∗)π(θ∗)p(θ(n)|θ∗)p(X|θ(n))π(θ(n))q(θ∗|θ(n)))
def MHstep(mcur, Scur):
mnew = mu_proposal_rvs(mcur)
logAnum = loglik(X, mnew, Scur) + mu_prior_logpdf(mnew) + mu_proposal_logpdf(mcur, mnew)
logAden = loglik(X, mcur, Scur) + mu_prior_logpdf(mcur) + mu_proposal_logpdf(mnew, mcur)
A = np.exp( logAnum - logAden )
U = np.random.uniform()
if U <= A:
mcur = mnew
else:
pass
return mcur, Scur
And repeat...
So to get a sample of size $$ N de la parte posterior de todo lo que necesitamos hacer ahora es el suministro de ciertas condiciones iniciales y de inicio de muestreo, también se puede modificar de la manera obvia para agregar una quemadura y mantener sólo un subconjunto de la parte posterior de muestras, etc.
mcur = np.array([0., 0.])
Scur = np.array([[1., 0.], [0., 1.]])
meanRVs = []
covRVs = []
nt = 0; N = 10
while nt < N:
mcur, Scur = MHstep(mcur, Scur)
meanRVs.append( mcur )
covRVs.append( Scur )
nt += 1
Usted puede ahora modificar el código anterior con algunos print ...
declaraciones, o incluso agregar usuario de entrada/salida lenta cada paso hacia abajo y ver exactamente lo que está sucediendo.