AllenDowney / ThinkBayes2

Text and code for the forthcoming second edition of Think Bayes, by Allen Downey.
http://allendowney.github.io/ThinkBayes2/
MIT License
1.8k stars 1.49k forks source link

Lincoln Index - Three parameter model #62

Closed zjachc closed 1 year ago

zjachc commented 1 year ago

I am receiving the following error when I attempt to compute the likelihood in the three parameter model: for N, p0, p1 in joint3_pmf.index:

ValueError: not enough values to unpack (expected 3, got 2)

I think the issue is that when I attempt to use make_joint using p1 and the joint2_pmf, I do not get the triplet, but rather only the pair, mean p1 is not attaching and thus the multi-index only has 2 items instead of three.

Do you have any suggestions about how best to fix?

Thank you

zjachc commented 1 year ago

Here is the entire script leading up to the problem:

Priors

params N, p0, p1, reuse prior_N

qs = np.linspace(0, 1, num=51) prior_p0 = make_uniform(qs, name='p0') prior_p1 = make_uniform(qs, name='p1')

Assemble into joint prior w/ 3-dim

put first two into DataFrame

joint2 = make_joint(prior_p0, prior_N) joint2.shape

Stack and put result into a Pmf

joint2_pmf = Pmf(joint2.stack()) joint2_pmf.head(3)

Use make_joint again to add in 3rd param

joint3 = make_joint(prior_p1, joint2_pmf) joint3.shape

joint3.head(3)

result is a DataFrame w/ values of N & p0 in a multi-index that goes down the rows

and values of p1 in an index that goes across the columns

apply stack again

joint3_pmf = Pmf(joint3.stack()) joint3_pmf.head(3)

joint3_pmf.shape

Loop that computes the likelihoods

likelihood = joint3_pmf.copy() observed = data.sum() x = data.copy()

for N, p0, p1 in joint3_pmf.index: x[0] = N - observed y = compute_probs(p0, p1) likelihood[N, p0, p1] = multinomial.pmf(x, N, y)

AllenDowney commented 1 year ago

Hi. To make sure I understand the question, are you reporting an error in my code or asking for help debugging?

zjachc commented 1 year ago

Hi - I used to code as it was written in the book and received an error; however, I'm not sure if there is a code error or a different issue and wanted to see if you had a suggestion as to why the code won't work as written.

AllenDowney commented 1 year ago

Here's the notebook where you can run the code (which works for me):

https://colab.research.google.com/github/AllenDowney/ThinkBayes2/blob/master/notebooks/chap15.ipynb

In the notebook you can print some of the intermediate values, or check the shape of the arrays/DataFrames. That should help with debugging.

zjachc commented 1 year ago

Shapes of the arrays match what was expected in the book. As do the heads up until joint3_pmf. At that point, the triplet doesn't show up, only a pair. It seems there is some issue with make_joint, Pmf, and stack, which has worked fine until now.

AllenDowney commented 1 year ago

When you run the code in the notebook I linked, does it work?

zjachc commented 1 year ago

Yes, it does. I understand the problem is on my end.

Do you have any thoughts as to why this issue emerged in this instance of the three-parameter, but never before?

AllenDowney commented 1 year ago

If you display joint3_pmf.index, does it have three columns?

zjachc commented 1 year ago

Yes - here's the first row:

MultiIndex([((0.0, 0.0), 32)

zjachc commented 1 year ago

MultiIndex([((0.0, 0.0), 32), ((0.0, 0.0), 37), ((0.0, 0.0), 42), ((0.0, 0.0), 47), ((0.0, 0.0), 52), ((0.0, 0.0), 57), ((0.0, 0.0), 62), ((0.0, 0.0), 67), ((0.0, 0.0), 72), ((0.0, 0.0), 77), ... ((1.0, 1.0), 302), ((1.0, 1.0), 307), ((1.0, 1.0), 312), ((1.0, 1.0), 317), ((1.0, 1.0), 322), ((1.0, 1.0), 327), ((1.0, 1.0), 332), ((1.0, 1.0), 337), ((1.0, 1.0), 342), ((1.0, 1.0), 347)], length=166464)

AllenDowney commented 1 year ago

Yup, that's a sequence of pairs, where the first of each pair is a pair, so that's not the same as a sequence of triples.

So either there's a difference between your code and mine or a difference between your environment and mine. I think it's unlikely to be an environment issue, so I'd look for a difference in the code.

zjachc commented 1 year ago

Thank you Allen - I will go through the code again. After running into the issue, I re-wrote the code and still had the problem and then copied it directly, but still no joy.

AllenDowney commented 1 year ago

Maybe put it in a Colab notebook. That would eliminate the environmental explanation. In the process, you might find the problem. If not, you could share the notebook with me.

zjachc commented 1 year ago

I will do that.

zjachc commented 1 year ago

Here's the script:

Three parameter model

Priors

params N, p0, p1, reuse prior_N

prior_N

qs = np.arange(32, 350, step=5) prior_N = make_uniform(qs, name='N') prior_N.head(3)

prior_p0, prior_p1

qs = np.linspace(0, 1, num=51) prior_p0 = make_uniform(qs, name='p0') prior_p1 = make_uniform(qs, name='p1')

prior_p0.head(3) prior_p1.head(3)

Assemble into joint prior w/ 3-dim

put first two into DataFrame

joint2 = make_joint(prior_p0, prior_N) joint2.shape joint2.head(10)

Stack and put result into a Pmf

joint2_pmf = Pmf(joint2.stack()) joint2_pmf.head(10)

Use make_joint again to add in 3rd param

joint3 = make_joint(prior_p1, joint2_pmf) joint3.shape

joint3.head(10)

result is a DataFrame w/ values of N & p0 in a multi-index that goes down the rows

and values of p1 in an index that goes across the columns

apply stack again

joint3_pmf = Pmf(joint3.stack()) joint3_pmf.head(10) joint3_pmf.index

joint3_pmf.shape

Loop that computes the likelihoods

likelihood = joint3_pmf.copy() observed = data.sum() x = data.copy()

from scipy.stats import multinomial

for N, p0, p1 in joint3_pmf.index: x[0] = N - observed y = compute_probs(p0, p1) likelihood[N, p0, p1] = multinomial.pmf(x, N, y)

zjachc commented 1 year ago

It's an environment issue, works in Jupyter but not Spyder unfortunately.

zjachc commented 1 year ago

What's interesting is that this does not work in Jupyter but does work in Spyder.

The following was copied directly - no modification.

Result is that the contour plot won't render. However, Spyder did not have this issue.

observed = k01 + k10 + k11

for N, p in joint_pmf.index: k00 = N - observed x = [k00, k01, k10, k11] q = 1-p y = [qq, qp, pq, pp] likelihood[N, p] = multinomial.pmf(x, N, y)


TypeError Traceback (most recent call last) Input In [24], in <cell line: 3>() 6 q = 1-p 7 y = [qq, qp, pq, pp] ----> 8 likelihood[N, p] = multinomial.pmf(x, N, y)

TypeError: 'numpy.float64' object does not support item assignment