ValueError:解压缩的值太多(预期为3)?

时间:2017-12-13 12:00:41

标签: python python-3.x ode mcmc

我一直遇到代码的问题我试图用模型我试图编码以下错误已经出现并且是一个相对新手我不确定如何解决它。

ValueError                                Traceback (most recent call last)
<ipython-input-2-5f21a0ce8185> in <module>()
     26         proposed[j] = proposed[j] + np.random.normal(0,propsigma[j])
     27         if (proposed[j]>0): # automatically reject moves if proposed parameter <=0
---> 28             alpha = np.exp(logistic_loglik(proposed,time,ExRatio,sig)-logistic_loglik(par_out[i-1,],time,ExRatio,sig))
     29             u = np.random.rand()
     30             if (u < alpha):

<ipython-input-2-5f21a0ce8185> in logistic_loglik(params, t, data, sig)
      3 # set up a function to return the log likelihood
      4 def logistic_loglik(params,t,data,sig):
----> 5     return sum(norm.logpdf(logistic(data, t, params),sig))
      6 
      7 # set standard deviations to be 10% of the population values

<ipython-input-1-c9480e66b7ef> in logistic(x, t, params)
      6 
      7 def logistic(x,t,params):
----> 8     S, R, A = x
      9     r, Nmax, delta_s, beta, gamma, delta_r, delta_a, Emax, H, MICs, MICr = params
     10     N = S + R

ValueError: too many values to unpack (expected 3) 

我正在尝试编写的模型是一个MCMC,可以将一些ODE与我在上下文中添加下面代码的一些数据相匹配。

import numpy as np
import matplotlib.pyplot as plt
from scipy.integrate import odeint

%matplotlib inline

def logistic(x,t,params):    
    S, R, A = x
    r, Nmax, delta_s, beta, gamma, delta_r, delta_a, Emax, H, MICs, MICr = params
    N = S + R
    E_s = 1 - (Emax * A**H)/(MICs**H + A**H)
    E_r = 1- (Emax * A**H)/(MICr**H + A**H)

    derivs = [r * (1 - N / Nmax ) * E_s * S - delta_s * S - ((beta * S * R)/N), 
     r * (1 - gamma) * (1 - N/Nmax) * E_r * R  - delta_r * R + ((beta * S * R)/N), - delta_a * A]


     return derivs

r = 0.5
Nmax = 10**7
delta_s = 0.025
beta = 10**-2
gamma = 0.5
delta_r = 0.025
delta_a = 0.003
Emax = 2
H = 2
MICs = 8
MICr = 2000

[r, Nmax, delta_s, beta, gamma, delta_r, delta_a, Emax, H, MICs, MICr] = params
S = 9 * 10**6
R = 10**5
A = 5.6
x0 = [S, R, A]

maxt = 2000
tstep = 1
t = np.arange(0,maxt,tstep)

def logistic_resid(params,t,data):
    return logistic(params,t)-data

logistic_out = odeint(logistic, x0, t, args=(params,))

time = np.array([0, 168, 336, 504, 672, 840, 1008, 1176, 1344, 1512, 1680, 1848, 2016, 2184, 2352, 2520, 2688, 2856])
ExRatio = np.array([2, 27, 43, 36, 39, 32, 27, 22, 13, 10, 14, 14, 4, 4, 7, 3, 3, 1])
ratio = 100* logistic_out[:,1]/(logistic_out[:,0]+logistic_out[:,1])
plt.plot(t,ratio)
plt.plot(time,ExRatio,'h')
xlabel('Position')
ylabel('Pollution')

New Cell

from scipy.stats import norm

# set up a function to return the log likelihood
def logistic_loglik(params,t,data,sig):
    return sum(norm.logpdf(logistic(data, t, params),sig))

# set standard deviations to be 10% of the population values
sig = ExRatio/10

# parameters for the MCMC
reps = 50000
npars = 3

# output matrix
par_out = np.ones(shape=(reps,npars))
# acceptance 
accept = np.zeros(shape=(reps,npars))
# proposal standard deviations. These have been pre-optimized.
propsigma = [0.05,20,5]

for i in range(1,reps):
    # make a copy of previous parameters
    par_out[i,] = par_out[i-1,]
    for j in range(npars):
        proposed = np.copy(par_out[i,:]) # we need to make a copy so that rejected moves don't affect the original matrix
        proposed[j] = proposed[j] + np.random.normal(0,propsigma[j])
        if (proposed[j]>0): # automatically reject moves if proposed parameter <=0 
            alpha = np.exp(logistic_loglik(proposed,time,ExRatio,sig)-logistic_loglik(par_out[i-1,],time,ExRatio,sig))
            u = np.random.rand()
            if (u < alpha):
                par_out[i,j] = proposed[j]
                accept[i,j] = 1

#print(sum(accept[range(101,reps),:])/(reps-100))


#plt.plot(par_out[:,0])
#plt.plot(par_out[range(101,reps),0])
#plt.plot(par_out[:,0],par_out[:,2])
plt.hist(par_out[range(101,reps),0],50)
print('\n')
a=np.mean(par_out[range(101,reps),0])

我认为它将我的参数误认为是其他东西,但这可能是错误的。 我正在使用Jupyter笔记本

2 个答案:

答案 0 :(得分:0)

如果S, R, A = x为空或者没有足够(太多)值来解包,则无法使用x

对于我所看到的,您正尝试使用变量x定义S,R和A值。只有当xlen时,才有可能这样做。如果您想将特定的x值分配给特定的S,R或A使用循环,或者如果您想要这样做你可以使用:

S, R, *A = x

这样变量S和R将具有x的第一和第二元素,而变量A具有其余部分。您可以将*放在任何变量之前,以使其存储在x中的过多值。

答案 1 :(得分:0)

立即语法错误

在你的电话中

---> 28             alpha = np.exp(logistic_loglik(proposed,time,ExRatio,sig)-logistic_loglik(par_out[i-1,],time,ExRatio,sig))

      4 def logistic_loglik(params,t,data,sig):
----> 5     return sum(norm.logpdf(logistic(data, t, params),sig))

最后使用

中定义的参数
      7 def logistic(x,t,params):
----> 8     S, R, A = x

导致错误的x是前一次调用的data,在第一次调用中设置为exTatio,在第一个块中定义为少数几个数组价值观您使用的逻辑可能有问题,因为exRatio的结构不是3个状态变量之一。

对数似然和概念的正确实现

您想要的是计算样本点的计算比率的对数似然,其中ExTime[k]的分布以正态分布给出,均值为ExRatio[k],方差为sig[k]设置为ExRatio[k]/10。在您的代码中,您需要做到这一点,使用建议的初始值求解ODE,计算比率并总结pdf值的日志:

# set up a function to return the log likelihood
def logistic_loglik(SRA0,ExTime,ExRatio,sig):
    # solve the ODE with the trial values `SRA0` and 
    # output the samples at the sample times `ExTime`
    logistic_out = odeint(logistic, SRA0, ExTime, args=(params,))
    # compute the ratios
    ratio = 100* logistic_out[:,1]/(logistic_out[:,0]+logistic_out[:,1])
    # return the summed log-likelihood
    return sum(norm.logpdf(ratio, ExRatio, sig))

尝试propsigma的变体导致最初快速收敛到定性合理的拟合。

propsigma       i       S, R, A = par_out[i]

[0.05,20.,5.]  59 [ 2.14767909    0.18163897   5.45312544]
[20,0.5,5.]    39 [ 56.48959836   0.50890498   5.80229728]
[5.,2.,5.]     79 [ 67.26394337   0.15865463   6.0213663 ]