I have been having issues with the code I am trying to right with the model I am trying to code the following error has appeared and being a relative novice I am unsure of how to resolve it.
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)
The model I am trying to code is an MCMC to fit some ODE's to some data I have added the code below for context.
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])
I think its mistaking my parameters for something else but that might be wrong. I am using Jupyter notebook
The immediate syntax error
In your call
to
where finally the paramerers are used as defined in
the
x
that causes the error is thedata
of the previous call which is set toexTatio
in the first call which is defined in your first block as an array of several handful of values. There might be something wrong with the logic that you use, as the structure ofexRatio
is not the one of 3 state variables.The correct implementation of the concept of the log-likelihood sum
What you want is to compute the log-likelihood of the computed ratios at your sample points where the distribution for
ExTime[k]
is given as a normal distribution with meanExRatio[k]
and variancesig[k]
which is set toExRatio[k]/10
. In your code you need to do exactly that, solve the ODE with the proposed initial values, compute the ratios and sum the logs of the pdf values:Trying variants of
propsigma
leads to initially rapid convergence to qualitatively reasonable fits.You cannot use
S, R, A = x
, ifx
is empty or has not enough (too much) values to unpack.For what I see, you are trying to define S, R and A values using the variable
x
. It is possible in that way only ifx
is thelen
of 3. If you want to assign certainx
values to specific S, R or A use loop, or if you want to do this that way you can use:S, R, *A = x
,this way the variable S and R will have the first and second element of x, and variable A the rest. You can put
*
before any variable to make it take the excessive values you store in x.