📚 The CoCalc Library - books, templates and other resources
License: OTHER
"""This file contains code used in "Think Stats",1by Allen B. Downey, available from greenteapress.com23Copyright 2013 Allen B. Downey4License: GNU GPLv3 http://www.gnu.org/licenses/gpl.html5"""67import thinkbayes8import thinkplot910from math import exp1112"""This file contains a solution to an exercise from Think Bayes,13by Allen B. Downey1415I got the idea from Tom Campbell-Ricketts author of the Maximum16Entropy blog at1718http://maximum-entropy-blog.blogspot.com1920And he got the idea from E.T. Jaynes, author of the classic21_Probability Theory: The Logic of Science_.2223Here's the version from Think Bayes:2425Radioactive decay is well modeled by a Poisson process; the26probability that an atom decays is the same at any point in time.2728Suppose that a radioactive source emits particles toward a Geiger29counter at an average rate of $r$ particles per second, but the30counter only registers a fraction, $f$, of the particles that hit it.31If $f$ is 10\% and the counter registers 15 particles in a one second32interval, what is the posterior distribution of $n$, the actual number33of particles that hit the counter, and $p$, the average rate particles34are emitted?3536"""3738FORMATS = ['pdf', 'eps', 'png']3940class Emitter(thinkbayes.Suite):41"""Represents hypotheses about r."""4243def __init__(self, rs, f=0.1):44"""Initializes the Suite.4546rs: sequence of hypothetical emission rates47f: fraction of particles registered48"""49detectors = [Detector(r, f) for r in rs]50thinkbayes.Suite.__init__(self, detectors)5152def Update(self, data):53"""Updates the Suite based on data.5455data: number of particles counted56"""57thinkbayes.Suite.Update(self, data)5859for detector in self.Values():60detector.Update()6162def Likelihood(self, data, hypo):63"""Likelihood of the data given the hypothesis.6465Args:66data: number of particles counted67hypo: emission rate, r6869Returns:70probability density of the data under the hypothesis71"""72detector = hypo73like = detector.SuiteLikelihood(data)74return like7576def DistOfR(self, name=''):77"""Returns the PMF of r."""78items = [(detector.r, prob) for detector, prob in self.Items()]79return thinkbayes.MakePmfFromItems(items, name=name)8081def DistOfN(self, name=''):82"""Returns the PMF of n."""83return thinkbayes.MakeMixture(self, name=name)848586class Emitter2(thinkbayes.Suite):87"""Represents hypotheses about r."""8889def __init__(self, rs, f=0.1):90"""Initializes the Suite.9192rs: sequence of hypothetical emission rates93f: fraction of particles registered94"""95detectors = [Detector(r, f) for r in rs]96thinkbayes.Suite.__init__(self, detectors)9798def Likelihood(self, data, hypo):99"""Likelihood of the data given the hypothesis.100101Args:102data: number of counted per unit time103hypo: emission rate, r104105Returns:106probability density of the data under the hypothesis107"""108return hypo.Update(data)109110def DistOfR(self, name=''):111"""Returns the PMF of r."""112items = [(detector.r, prob) for detector, prob in self.Items()]113return thinkbayes.MakePmfFromItems(items, name=name)114115def DistOfN(self, name=''):116"""Returns the PMF of n."""117return thinkbayes.MakeMixture(self, name=name)118119120class Detector(thinkbayes.Suite):121"""Represents hypotheses about n."""122123def __init__(self, r, f, high=500, step=5):124"""Initializes the suite.125126r: known emission rate, r127f: fraction of particles registered128high: maximum number of particles, n129step: step size between hypothetical values of n130"""131pmf = thinkbayes.MakePoissonPmf(r, high, step=step)132thinkbayes.Suite.__init__(self, pmf, name=r)133self.r = r134self.f = f135136def Likelihood(self, data, hypo):137"""Likelihood of the data given the hypothesis.138139data: number of particles counted140hypo: number of particles hitting the counter, n141"""142k = data143n = hypo144p = self.f145146return thinkbayes.EvalBinomialPmf(k, n, p)147148def SuiteLikelihood(self, data):149"""Adds up the total probability of the data under the suite.150151data: number of particles counted152"""153total = 0154for hypo, prob in self.Items():155like = self.Likelihood(data, hypo)156total += prob * like157return total158159160def main():161k = 15162f = 0.1163164# plot Detector suites for a range of hypothetical r165thinkplot.PrePlot(num=3)166for r in [100, 250, 400]:167suite = Detector(r, f, step=1)168suite.Update(k)169thinkplot.Pmf(suite)170print suite.MaximumLikelihood()171172thinkplot.Save(root='jaynes1',173xlabel='Number of particles (n)',174ylabel='PMF',175formats=FORMATS)176177# plot the posterior distributions of r and n178hypos = range(1, 501, 5)179suite = Emitter2(hypos, f=f)180suite.Update(k)181182thinkplot.PrePlot(num=2)183post_r = suite.DistOfR(name='posterior r')184post_n = suite.DistOfN(name='posterior n')185186thinkplot.Pmf(post_r)187thinkplot.Pmf(post_n)188189thinkplot.Save(root='jaynes2',190xlabel='Emission rate',191ylabel='PMF',192formats=FORMATS)193194195if __name__ == '__main__':196main()197198199