This notebook presents solutions to exercises in Think Bayes.
Copyright 2016 Allen B. Downey
MIT License: https://opensource.org/licenses/MIT
In [1]:
from __future__ import print_function, division
from thinkbayes2 import Hist, Pmf
% matplotlib inline
Exercise 2.1 In Section 2.3 I said that the solution to the cookie problem generalizes to the case where we draw multiple cookies with replacement.
But in the more likely scenario where we eat the cookies we draw, the likelihood of each draw depends on the previous draws.
Modify the solution in this chapter to handle selection without replacement. Hint: add instance variables to Cookie to represent the hypothetical state of the bowls, and modify Likelihood accordingly. You might want to define a Bowl object.
Solution Here's the original solution from the book:
In [2]:
pmf = Pmf()
pmf.Set('Bowl 1', 0.5)
pmf.Set('Bowl 2', 0.5)
pmf.Mult('Bowl 1', 0.75)
pmf.Mult('Bowl 2', 0.5)
pmf.Normalize()
pmf.Print()
We could write it more concisely like this:
In [3]:
pmf = Pmf(['Bowl 1', 'Bowl 2'])
pmf['Bowl 1'] *= 0.75
pmf['Bowl 2'] *= 0.5
pmf.Normalize()
pmf.Print()
And we can do a second update, with a chocolate cookie, like this:
In [4]:
pmf['Bowl 1'] *= 0.25
pmf['Bowl 2'] *= 0.5
pmf.Normalize()
pmf.Print()
Now let's solve the version of the problem where we don't replace the cookies.
We'll need an object to keep track of the number of cookies in each bowl. I'll use a Hist object, defined in thinkbayes2:
In [5]:
bowl1 = Hist(dict(vanilla=30, chocolate=10))
bowl2 = Hist(dict(vanilla=20, chocolate=20))
bowl1.Print()
Now I'll make a Pmf that contains the two bowls, giving them equal probability.
In [6]:
pmf = Pmf([bowl1, bowl2])
pmf.Print()
Here's a likelihood function that takes hypo
, which is one of the Hist objects that represents a bowl, and data
, which is either 'vanilla'
or 'chocolate'
.
likelihood
computes the likelihood of the data under the hypothesis, and as a side effect, it removes one of the cookies from hypo
In [7]:
def likelihood(hypo, data):
like = hypo[data] / hypo.Total()
if like:
hypo[data] -= 1
return like
Now for the update. We have to loop through the hypotheses and compute the likelihood of the data under each hypothesis.
In [8]:
def update(pmf, data):
for hypo in pmf:
pmf[hypo] *= likelihood(hypo, data)
return pmf.Normalize()
Here's the first update. The posterior probabilities are the same as what we got before, but notice that the number of cookies in each Hist has been updated.
In [9]:
update(pmf, 'vanilla')
pmf.Print()
So when we update again with a chocolate cookies, we get different likelihoods, and different posteriors.
In [10]:
update(pmf, 'chocolate')
pmf.Print()
If we get 10 more chocolate cookies, that eliminates Bowl 1 completely
In [11]:
for i in range(10):
update(pmf, 'chocolate')
print(pmf[bowl1])
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]:
In [ ]: