Hi,
I've been working on implementing the straight-line fitting model
described by Brandon Kelly (
http://xxx.lanl.gov/abs/0705.2774) in
PyMC. The model is designed to fit a straight line in the case where
there are measurement errors in both the independent and dependent
variables and intrinsic scatter in the underlying relationship. The
underlying relationship is eta_i = alpha + beta*xi_i + epsilon, where
i indexes the data points and epsilon has a Normal distribution with
mean = 0 and precision = tau. The observed data are xdata_i = xi_i +
epsilon_xi and ydata_i = eta_i + epsilon_eta, where epsilon_xi and
epsilon_eta have Normal distributions with means = 0 and *known*
precisions tau_x and tau_y. (Kelly's model also includes correlation
between the measurement errors, but I'm going to ignore that for the
sake of simplicity.) The priors for alpha, beta, and tau are Normal,
Normal, and Gamma, respectively. The prior for the distribution of xi
is also Normal. (Interestingly, the naive flat prior for the
distribution of xi leads to results identical to ordinary least
squares, i.e., underestimate of the slope and overestimate of the
intercept.)
My problem is that often (but not absolutely always) the MCMC sampling
favors very high values of tau (i.e., no intrinsic scatter). I've run
the same model with JAGS, and I never see the same issue. Part of the
difference may be that JAGS uses a different sampler for tau
(ConjugateGamma for JAGS vs Metropolis for PyMC), but otherwise I'm
not sure what's going on or how to fix it. The only other clue I've
discovered is that the acceptance ratio for the posterior samples of
tau becomes quite large (~0.8). So, I was wondering if any of you
folks have some suggestions. I've appended a simple Python script to
help others reproduce my results. The chain often needs to be run for
several hundred thousand iterations to see tau wander off to very high
values.
Thanks,
Todd
++++++++
import pymc
# "True" values of the parameters
n_data = 100
intercept = 15.
slope = 1.5
sigma = 8.
sigma_x = 8.
sigma_y = 8.
# Generate simulated data
xi_true = 25. + np.random.randn(n_data)*15.
eta_true = intercept + slope*xi_true + np.random.randn(n_data)*sigma
x_data = xi_true + np.random.randn(n_data)*sigma_x
y_data = eta_true + np.random.randn(n_data)*sigma_y
# Initial values
beta0, alpha0 = np.polyfit(x_data, y_data, 1)
var0 = ((alpha0 + beta0*x_data - y_data)**2.).sum()/n_data
tau0 = 1./var0
tau_x = 1./sigma_x**2.
tau_y = 1./sigma_y**2.
# Intercept, slope, and intrinsic scatter
alpha = pymc.Normal('alpha', 0., 1.e-6, value=alpha0)
beta = pymc.Normal('beta', 0., 1.e-6, value=beta0)
tau = pymc.Gamma('tau', 0.001, 0.001, value=tau0)
# Model for xi
mu_xi = pymc.Normal('mu_xi', 0., 1.e-6, value=x_data.mean())
tau_xi = pymc.Gamma('tau_xi', 0.001, 0.001, value=1./x_data.var())
xi = pymc.Normal('xi', mu_xi, tau_xi, value=x_data)
@pymc.deterministic
def mu(xi=xi, alpha=alpha, beta=beta):
return alpha + beta*xi
eta = pymc.Normal('eta', mu, tau)
x = pymc.Normal('x', xi, tau_x, value=x_data, observed=True)
y = pymc.Normal('y', eta, tau_y, value=y_data, observed=True)
M = pymc.MCMC([alpha, beta, tau, mu, mu_xi, tau_xi, xi, eta, x, y])
M.sample(500000, 10000, 10)