带有pymc的参数向量的非线性回归

时间:2014-11-19 23:52:44

标签: pymc pymc3

我目前使用scipy.optimize.minimize和scipy.optimize.leastsq对我的数据集执行非线性回归。我想使用PyMC(3)来研究拟合程序中涉及的所有参数的后验。我在SO上遇到了这个previous answer

这是一个非常好的例子,我看到的大多数其他例子都是线性回归。但是,这个例子并不完全适合我的目的。我的模型有可变数量的参数,其中我将拟合一个子集。该子集通常在1到20个参数的范围内,但有时更多。使用scipy minimizers,这些不同的参数以1D np.ndarray,p的形式传递给成本函数,例如

def chi2(p, *args):
    xdata = args[0]
    return p[0] + xdata * p[1] + ........

在上面给出的链接中,@ pymc.deterministic装饰高斯函数有关键字参数。这对我来说是不切实际的,因为相同的代码块需要处理不同(和相当大)的参数数量。有没有办法提供参数矢量?我还必须提供每个参数的先验列表。但是,我有一个每个参数[(min,max)...]的下限和上限列表,这样就不会有问题了。

3 个答案:

答案 0 :(得分:3)

由于您使用的是标准优化例程,因此您可以将最小化的函数表示为对数似然。如果它表示为对数似然,您想要做的就是探索参数的后验分布,您可能会发现 emcee 更容易使用。就我而言,在开始研究mcmc方法之前,我实际上是在最小化对数似然。

from scipy.optimize import minimize

bnds = ((.0001,20),(.0001,20),(.0001,20),(.0001,20))

solution = minimize(my_function_ll, np.array([1.1,1.2,1.3,1.4]), 
                    args=(my_data),
                    bounds=bnds )

我所要做的就是将my_function_ll()插入这样的emcee:

import emcee

# for reproducible results
np.random.seed(0)

ndim = 4  # number of parameters in the model
nwalkers = 10  # number of MCMC walkers
nburn = 1000  # "burn-in" period to let chains stabilize
nsteps = 10000  # number of MCMC steps to take

# we'll start at random locations between 0 and 2
starting_guesses = 2*np.random.rand(nwalkers, ndim)

def log_prior(theta):
    x1,x2,x3,x4 = theta
    # here you can specify boundary. In my case I was using 0 - 20
    if 0.0001 < x1 < 20 and 0.0001 < x2 < 20 and 0.0001 < x3 < 20 and 0.0001 < x4 < 20:
        return 0.0
    return -np.inf

def log_posterior(theta, observation_array):
    lp = log_prior(theta)
    if not np.isfinite(lp):
        return -np.inf    
    return log_prior(theta) + my_function_ll(theta, observation_array) 

sampler = emcee.EnsembleSampler(nwalkers, ndim, log_posterior, 
                                args=[my_data])
sampler.run_mcmc(starting_guesses, nsteps)

sample = sampler.chain[:, nburn:, :].reshape(-1, 4)

现在您可以比较MCMC和MLE结果:

print "MLE: ", solution.x
print "MCMC: ", sample.mean(0)

答案 1 :(得分:2)

对于一组参数,通常最好使用矢量并取点积:

@deterministic
def theta(beta=beta):
    return beta.dot(X)

或者如果你想要一个明确的基线平均值:

@deterministic
def theta(mu=mu, beta=beta):
    return mu + beta.dot(X)

(这是所有PyMC 2.3)

答案 2 :(得分:0)

以下链接包含了我可以用来开展的大量信息。

https://groups.google.com/forum/#!msg/pymc/WUg0tZjNAL8/jsVRFe1DMT4J