Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
allendowney
GitHub Repository: allendowney/thinkbayes2
Path: blob/master/scripts/redline.py
1901 views
1
"""This file contains code used in "Think Bayes",
2
by Allen B. Downey, available from greenteapress.com
3
4
Copyright 2013 Allen B. Downey
5
License: GNU GPLv3 http://www.gnu.org/licenses/gpl.html
6
"""
7
8
from __future__ import print_function, division
9
10
import thinkbayes2
11
12
import thinkplot
13
import numpy
14
15
import math
16
import random
17
import sys
18
19
FORMATS = ['pdf', 'eps', 'png', 'jpg']
20
21
"""
22
Notation guide:
23
24
z: time between trains
25
x: time since the last train
26
y: time until the next train
27
28
zb: distribution of z as seen by a random arrival
29
30
"""
31
32
# longest hypothetical time between trains, in seconds
33
34
UPPER_BOUND = 1200
35
36
# observed gaps between trains, in seconds
37
# collected using code in redline_data.py, run daily 4-6pm
38
# for 5 days, Monday 6 May 2013 to Friday 10 May 2013
39
40
OBSERVED_GAP_TIMES = [
41
428.0, 705.0, 407.0, 465.0, 433.0, 425.0, 204.0, 506.0, 143.0, 351.0,
42
450.0, 598.0, 464.0, 749.0, 341.0, 586.0, 754.0, 256.0, 378.0, 435.0,
43
176.0, 405.0, 360.0, 519.0, 648.0, 374.0, 483.0, 537.0, 578.0, 534.0,
44
577.0, 619.0, 538.0, 331.0, 186.0, 629.0, 193.0, 360.0, 660.0, 484.0,
45
512.0, 315.0, 457.0, 404.0, 740.0, 388.0, 357.0, 485.0, 567.0, 160.0,
46
428.0, 387.0, 901.0, 187.0, 622.0, 616.0, 585.0, 474.0, 442.0, 499.0,
47
437.0, 620.0, 351.0, 286.0, 373.0, 232.0, 393.0, 745.0, 636.0, 758.0,
48
]
49
50
51
def BiasPmf(pmf, label=None, invert=False):
52
"""Returns the Pmf with oversampling proportional to value.
53
54
If pmf is the distribution of true values, the result is the
55
distribution that would be seen if values are oversampled in
56
proportion to their values; for example, if you ask students
57
how big their classes are, large classes are oversampled in
58
proportion to their size.
59
60
If invert=True, computes in inverse operation; for example,
61
unbiasing a sample collected from students.
62
63
Args:
64
pmf: Pmf object.
65
label: string name for the new Pmf.
66
invert: boolean
67
68
Returns:
69
Pmf object
70
"""
71
new_pmf = pmf.Copy(label=label)
72
73
for x in pmf.Values():
74
if invert:
75
new_pmf.Mult(x, 1.0/x)
76
else:
77
new_pmf.Mult(x, x)
78
79
new_pmf.Normalize()
80
return new_pmf
81
82
83
def UnbiasPmf(pmf, label=None):
84
"""Returns the Pmf with oversampling proportional to 1/value.
85
86
Args:
87
pmf: Pmf object.
88
label: string label for the new Pmf.
89
90
Returns:
91
Pmf object
92
"""
93
return BiasPmf(pmf, label, invert=True)
94
95
96
def MakeUniformPmf(low, high):
97
"""Make a uniform Pmf.
98
99
low: lowest value (inclusive)
100
high: highest value (inclusive)
101
"""
102
xs = MakeRange(low, high)
103
pmf = thinkbayes2.Pmf(xs)
104
return pmf
105
106
107
def MakeRange(low=10, high=None, skip=10):
108
"""Makes a range representing possible gap times in seconds.
109
110
low: where to start
111
high: where to end
112
skip: how many to skip
113
"""
114
if high is None:
115
high = UPPER_BOUND
116
117
xs = numpy.arange(low, high+skip, skip)
118
return xs
119
120
121
class WaitTimeCalculator(object):
122
"""Encapsulates the forward inference process.
123
124
Given the actual distribution of gap times (z),
125
computes the distribution of gaps as seen by
126
a random passenger (zb), which yields the distribution
127
of wait times (y) and the distribution of elapsed times (x).
128
"""
129
130
def __init__(self, pmf, inverse=False):
131
"""Constructor.
132
133
pmf: Pmf of either z or zb
134
inverse: boolean, true if pmf is zb, false if pmf is z
135
"""
136
if inverse:
137
self.pmf_zb = pmf
138
self.pmf_z = UnbiasPmf(pmf, label="z")
139
else:
140
self.pmf_z = pmf
141
self.pmf_zb = BiasPmf(pmf, label="zb")
142
143
# distribution of wait time
144
self.pmf_y = PmfOfWaitTime(self.pmf_zb)
145
146
# the distribution of elapsed time is the same as the
147
# distribution of wait time
148
self.pmf_x = self.pmf_y
149
150
def GenerateSampleWaitTimes(self, n):
151
"""Generates a random sample of wait times.
152
153
n: sample size
154
155
Returns: sequence of values
156
"""
157
cdf_y = thinkbayes2.Cdf(self.pmf_y)
158
sample = cdf_y.Sample(n)
159
return sample
160
161
def GenerateSampleGaps(self, n):
162
"""Generates a random sample of gaps seen by passengers.
163
164
n: sample size
165
166
Returns: sequence of values
167
"""
168
cdf_zb = thinkbayes2.Cdf(self.pmf_zb)
169
sample = cdf_zb.Sample(n)
170
return sample
171
172
def GenerateSamplePassengers(self, lam, n):
173
"""Generates a sample wait time and number of arrivals.
174
175
lam: arrival rate in passengers per second
176
n: number of samples
177
178
Returns: list of (k1, y, k2) tuples
179
k1: passengers there on arrival
180
y: wait time
181
k2: passengers arrived while waiting
182
"""
183
zs = self.GenerateSampleGaps(n)
184
xs, ys = SplitGaps(zs)
185
186
res = []
187
for x, y in zip(xs, ys):
188
k1 = numpy.random.poisson(lam * x)
189
k2 = numpy.random.poisson(lam * y)
190
res.append((k1, y, k2))
191
192
return res
193
194
def PlotPmfs(self, root='redline0'):
195
"""Plots the computed Pmfs.
196
197
root: string
198
"""
199
pmfs = ScaleDists([self.pmf_z, self.pmf_zb], 1.0/60)
200
201
thinkplot.Clf()
202
thinkplot.PrePlot(2)
203
thinkplot.Pmfs(pmfs)
204
thinkplot.Save(root=root,
205
xlabel='Time (min)',
206
ylabel='CDF',
207
formats=FORMATS)
208
209
210
def MakePlot(self, root='redline2'):
211
"""Plots the computed CDFs.
212
213
root: string
214
"""
215
print('Mean z', self.pmf_z.Mean() / 60)
216
print('Mean zb', self.pmf_zb.Mean() / 60)
217
print('Mean y', self.pmf_y.Mean() / 60)
218
219
cdf_z = self.pmf_z.MakeCdf()
220
cdf_zb = self.pmf_zb.MakeCdf()
221
cdf_y = self.pmf_y.MakeCdf()
222
223
cdfs = ScaleDists([cdf_z, cdf_zb, cdf_y], 1.0/60)
224
225
thinkplot.Clf()
226
thinkplot.PrePlot(3)
227
thinkplot.Cdfs(cdfs)
228
thinkplot.Save(root=root,
229
xlabel='Time (min)',
230
ylabel='CDF',
231
formats=FORMATS)
232
233
234
def SplitGaps(zs):
235
"""Splits zs into xs and ys.
236
237
zs: sequence of gaps
238
239
Returns: tuple of sequences (xs, ys)
240
"""
241
xs = [random.uniform(0, z) for z in zs]
242
ys = [z-x for z, x in zip(zs, xs)]
243
return xs, ys
244
245
246
def PmfOfWaitTime(pmf_zb):
247
"""Distribution of wait time.
248
249
pmf_zb: dist of gap time as seen by a random observer
250
251
Returns: dist of wait time (also dist of elapsed time)
252
"""
253
metapmf = thinkbayes2.Pmf()
254
for gap, prob in pmf_zb.Items():
255
uniform = MakeUniformPmf(0, gap)
256
metapmf.Set(uniform, prob)
257
258
pmf_y = thinkbayes2.MakeMixture(metapmf, label='y')
259
return pmf_y
260
261
262
def ScaleDists(dists, factor):
263
"""Scales each of the distributions in a sequence.
264
265
dists: sequence of Pmf or Cdf
266
factor: float scale factor
267
"""
268
return [dist.Scale(factor) for dist in dists]
269
270
271
class ElapsedTimeEstimator(object):
272
"""Uses the number of passengers to estimate time since last train."""
273
274
def __init__(self, wtc, lam, num_passengers):
275
"""Constructor.
276
277
pmf_x: expected distribution of elapsed time
278
lam: arrival rate in passengers per second
279
num_passengers: # passengers seen on the platform
280
"""
281
# prior for elapsed time
282
self.prior_x = Elapsed(wtc.pmf_x, label='prior x')
283
284
# posterior of elapsed time (based on number of passengers)
285
self.post_x = self.prior_x.Copy(label='posterior x')
286
self.post_x.Update((lam, num_passengers))
287
288
# predictive distribution of wait time
289
self.pmf_y = PredictWaitTime(wtc.pmf_zb, self.post_x)
290
291
def MakePlot(self, root='redline3'):
292
"""Plot the CDFs.
293
294
root: string
295
"""
296
# observed gaps
297
cdf_prior_x = self.prior_x.MakeCdf()
298
cdf_post_x = self.post_x.MakeCdf()
299
cdf_y = self.pmf_y.MakeCdf()
300
301
cdfs = ScaleDists([cdf_prior_x, cdf_post_x, cdf_y], 1.0/60)
302
303
thinkplot.Clf()
304
thinkplot.PrePlot(3)
305
thinkplot.Cdfs(cdfs)
306
thinkplot.Save(root=root,
307
xlabel='Time (min)',
308
ylabel='CDF',
309
formats=FORMATS)
310
311
312
class ArrivalRate(thinkbayes2.Suite):
313
"""Represents the distribution of arrival rates (lambda)."""
314
315
def Likelihood(self, data, hypo):
316
"""Computes the likelihood of the data under the hypothesis.
317
318
Evaluates the Poisson PMF for lambda and k.
319
320
hypo: arrival rate in passengers per second
321
data: tuple of elapsed_time and number of passengers
322
"""
323
lam = hypo
324
x, k = data
325
like = thinkbayes2.EvalPoissonPmf(k, lam * x)
326
return like
327
328
329
class ArrivalRateEstimator(object):
330
"""Estimates arrival rate based on passengers that arrive while waiting.
331
"""
332
333
def __init__(self, passenger_data):
334
"""Constructor
335
336
passenger_data: sequence of (k1, y, k2) pairs
337
"""
338
# range for lambda
339
low, high = 0, 5
340
n = 51
341
hypos = numpy.linspace(low, high, n) / 60
342
343
self.prior_lam = ArrivalRate(hypos, label='prior')
344
self.prior_lam.Remove(0)
345
346
self.post_lam = self.prior_lam.Copy(label='posterior')
347
348
for _k1, y, k2 in passenger_data:
349
self.post_lam.Update((y, k2))
350
351
print('Mean posterior lambda', self.post_lam.Mean())
352
353
def MakePlot(self, root='redline1'):
354
"""Plot the prior and posterior CDF of passengers arrival rate.
355
356
root: string
357
"""
358
thinkplot.Clf()
359
thinkplot.PrePlot(2)
360
361
# convert units to passengers per minute
362
prior = self.prior_lam.MakeCdf().Scale(60)
363
post = self.post_lam.MakeCdf().Scale(60)
364
365
thinkplot.Cdfs([prior, post])
366
367
thinkplot.Save(root=root,
368
xlabel='Arrival rate (passengers / min)',
369
ylabel='CDF',
370
formats=FORMATS)
371
372
373
class Elapsed(thinkbayes2.Suite):
374
"""Represents the distribution of elapsed time (x)."""
375
376
def Likelihood(self, data, hypo):
377
"""Computes the likelihood of the data under the hypothesis.
378
379
Evaluates the Poisson PMF for lambda and k.
380
381
hypo: elapsed time since the last train
382
data: tuple of arrival rate and number of passengers
383
"""
384
x = hypo
385
lam, k = data
386
like = thinkbayes2.EvalPoissonPmf(k, lam * x)
387
return like
388
389
390
def PredictWaitTime(pmf_zb, pmf_x):
391
"""Computes the distribution of wait times.
392
393
Enumerate all pairs of zb from pmf_zb and x from pmf_x,
394
and accumulate the distribution of y = z - x.
395
396
pmf_zb: distribution of gaps seen by random observer
397
pmf_x: distribution of elapsed time
398
"""
399
pmf_y = pmf_zb - pmf_x
400
pmf_y.label = 'pred y'
401
RemoveNegatives(pmf_y)
402
return pmf_y
403
404
405
def RemoveNegatives(pmf):
406
"""Removes negative values from a PMF.
407
408
pmf: Pmf
409
"""
410
for val in list(pmf.Values()):
411
if val < 0:
412
pmf.Remove(val)
413
pmf.Normalize()
414
415
416
class Gaps(thinkbayes2.Suite):
417
"""Represents the distribution of gap times,
418
as updated by an observed waiting time."""
419
420
def Likelihood(self, data, hypo):
421
"""The likelihood of the data under the hypothesis.
422
423
If the actual gap time is z, what is the likelihood
424
of waiting y seconds?
425
426
hypo: actual time between trains
427
data: observed wait time
428
"""
429
z = hypo
430
y = data
431
if y > z:
432
return 0
433
return 1.0 / z
434
435
436
class GapDirichlet(thinkbayes2.Dirichlet):
437
"""Represents the distribution of prevalences for each
438
gap time."""
439
440
def __init__(self, xs):
441
"""Constructor.
442
443
xs: sequence of possible gap times
444
"""
445
n = len(xs)
446
thinkbayes2.Dirichlet.__init__(self, n)
447
self.xs = xs
448
self.mean_zbs = []
449
450
def PmfMeanZb(self):
451
"""Makes the Pmf of mean zb.
452
453
Values stored in mean_zbs.
454
"""
455
return thinkbayes2.Pmf(self.mean_zbs)
456
457
def Preload(self, data):
458
"""Adds pseudocounts to the parameters.
459
460
data: sequence of pseudocounts
461
"""
462
thinkbayes2.Dirichlet.Update(self, data)
463
464
def Update(self, data):
465
"""Computes the likelihood of the data.
466
467
data: wait time observed by random arrival (y)
468
469
Returns: float probability
470
"""
471
k, y = data
472
473
print(k, y)
474
prior = self.PredictivePmf(self.xs)
475
gaps = Gaps(prior)
476
gaps.Update(y)
477
probs = gaps.Probs(self.xs)
478
479
self.params += numpy.array(probs)
480
481
482
class GapDirichlet2(GapDirichlet):
483
"""Represents the distribution of prevalences for each
484
gap time."""
485
486
def Update(self, data):
487
"""Computes the likelihood of the data.
488
489
data: wait time observed by random arrival (y)
490
491
Returns: float probability
492
"""
493
k, y = data
494
495
# get the current best guess for pmf_z
496
pmf_zb = self.PredictivePmf(self.xs)
497
498
# use it to compute prior pmf_x, pmf_y, pmf_z
499
wtc = WaitTimeCalculator(pmf_zb, inverse=True)
500
501
# use the observed passengers to estimate posterior pmf_x
502
elapsed = ElapsedTimeEstimator(wtc,
503
lam=0.0333,
504
num_passengers=k)
505
506
# use posterior_x and observed y to estimate observed z
507
obs_zb = elapsed.post_x + Floor(y)
508
probs = obs_zb.Probs(self.xs)
509
510
mean_zb = obs_zb.Mean()
511
self.mean_zbs.append(mean_zb)
512
print(k, y, mean_zb)
513
514
# use observed z to update beliefs about pmf_z
515
self.params += numpy.array(probs)
516
517
518
class GapTimeEstimator(object):
519
"""Infers gap times using passenger data."""
520
521
def __init__(self, xs, pcounts, passenger_data):
522
self.xs = xs
523
self.pcounts = pcounts
524
self.passenger_data = passenger_data
525
526
self.wait_times = [y for _k1, y, _k2 in passenger_data]
527
self.pmf_y = thinkbayes2.Pmf(self.wait_times, label="y")
528
529
dirichlet = GapDirichlet2(self.xs)
530
dirichlet.params /= 1.0
531
532
dirichlet.Preload(self.pcounts)
533
dirichlet.params /= 20.0
534
535
self.prior_zb = dirichlet.PredictivePmf(self.xs, label="prior zb")
536
537
for k1, y, _k2 in passenger_data:
538
dirichlet.Update((k1, y))
539
540
self.pmf_mean_zb = dirichlet.PmfMeanZb()
541
542
self.post_zb = dirichlet.PredictivePmf(self.xs, label="post zb")
543
self.post_z = UnbiasPmf(self.post_zb, label="post z")
544
545
def PlotPmfs(self):
546
"""Plot the PMFs."""
547
print('Mean y', self.pmf_y.Mean())
548
print('Mean z', self.post_z.Mean())
549
print('Mean zb', self.post_zb.Mean())
550
551
thinkplot.Pmf(self.pmf_y)
552
thinkplot.Pmf(self.post_z)
553
thinkplot.Pmf(self.post_zb)
554
555
def MakePlot(self):
556
"""Plot the CDFs."""
557
thinkplot.Cdf(self.pmf_y.MakeCdf())
558
thinkplot.Cdf(self.prior_zb.MakeCdf())
559
thinkplot.Cdf(self.post_zb.MakeCdf())
560
thinkplot.Cdf(self.pmf_mean_zb.MakeCdf())
561
thinkplot.Show()
562
563
564
def Floor(x, factor=10):
565
"""Rounds down to the nearest multiple of factor.
566
567
When factor=10, all numbers from 10 to 19 get floored to 10.
568
"""
569
return int(x/factor) * factor
570
571
572
def TestGte():
573
"""Tests the GapTimeEstimator."""
574
random.seed(17)
575
576
xs = [60, 120, 240]
577
578
gap_times = [60, 60, 60, 60, 60, 120, 120, 120, 240, 240]
579
580
# distribution of gap time (z)
581
pdf_z = thinkbayes2.EstimatedPdf(gap_times)
582
pmf_z = pdf_z.MakePmf(xs=xs, label="z")
583
584
wtc = WaitTimeCalculator(pmf_z, inverse=False)
585
586
lam = 0.0333
587
n = 100
588
passenger_data = wtc.GenerateSamplePassengers(lam, n)
589
590
pcounts = [0, 0, 0]
591
592
ite = GapTimeEstimator(xs, pcounts, passenger_data)
593
594
thinkplot.Clf()
595
596
# thinkplot.Cdf(wtc.pmf_z.MakeCdf(label="actual z"))
597
thinkplot.Cdf(wtc.pmf_zb.MakeCdf(label="actual zb"))
598
ite.MakePlot()
599
600
601
class WaitMixtureEstimator(object):
602
"""Encapsulates the process of estimating wait time with uncertain lam.
603
"""
604
605
def __init__(self, wtc, are, num_passengers=15):
606
"""Constructor.
607
608
wtc: WaitTimeCalculator
609
are: ArrivalTimeEstimator
610
num_passengers: number of passengers seen on the platform
611
"""
612
self.metapmf = thinkbayes2.Pmf()
613
614
for lam, prob in sorted(are.post_lam.Items()):
615
ete = ElapsedTimeEstimator(wtc, lam, num_passengers)
616
self.metapmf.Set(ete.pmf_y, prob)
617
618
self.mixture = thinkbayes2.MakeMixture(self.metapmf)
619
620
lam = are.post_lam.Mean()
621
ete = ElapsedTimeEstimator(wtc, lam, num_passengers)
622
self.point = ete.pmf_y
623
624
def MakePlot(self, root='redline4'):
625
"""Makes a plot showing the mixture."""
626
thinkplot.Clf()
627
628
# plot the MetaPmf
629
for pmf, prob in sorted(self.metapmf.Items()):
630
cdf = pmf.MakeCdf().Scale(1.0/60)
631
width = 2/math.log(-math.log(prob))
632
thinkplot.Plot(cdf.xs, cdf.ps,
633
alpha=0.2, linewidth=width, color='blue',
634
label='')
635
636
# plot the mixture and the distribution based on a point estimate
637
thinkplot.PrePlot(2)
638
#thinkplot.Cdf(self.point.MakeCdf(label='point').Scale(1.0/60))
639
thinkplot.Cdf(self.mixture.MakeCdf(label='mix').Scale(1.0/60))
640
641
thinkplot.Save(root=root,
642
xlabel='Wait time (min)',
643
ylabel='CDF',
644
formats=FORMATS,
645
axis=[0,10,0,1])
646
647
648
649
def GenerateSampleData(gap_times, lam=0.0333, n=10):
650
"""Generates passenger data based on actual gap times.
651
652
gap_times: sequence of float
653
lam: arrival rate in passengers per second
654
n: number of simulated observations
655
"""
656
xs = MakeRange(low=10)
657
pdf_z = thinkbayes2.EstimatedPdf(gap_times)
658
pmf_z = pdf_z.MakePmf(xs=xs, label="z")
659
660
wtc = WaitTimeCalculator(pmf_z, inverse=False)
661
passenger_data = wtc.GenerateSamplePassengers(lam, n)
662
return wtc, passenger_data
663
664
665
def RandomSeed(x):
666
"""Initialize the random and numpy.random generators.
667
668
x: int seed
669
"""
670
random.seed(x)
671
numpy.random.seed(x)
672
673
674
def RunSimpleProcess(gap_times, lam=0.0333, num_passengers=15, plot=True):
675
"""Runs the basic analysis and generates figures.
676
677
gap_times: sequence of float
678
lam: arrival rate in passengers per second
679
num_passengers: int number of passengers on the platform
680
plot: boolean, whether to generate plots
681
682
Returns: WaitTimeCalculator, ElapsedTimeEstimator
683
"""
684
global UPPER_BOUND
685
UPPER_BOUND = 1200
686
687
cdf_z = thinkbayes2.Cdf(gap_times).Scale(1.0/60)
688
print('CI z', cdf_z.CredibleInterval(90))
689
690
xs = MakeRange(low=10)
691
692
pdf_z = thinkbayes2.EstimatedPdf(gap_times)
693
pmf_z = pdf_z.MakePmf(xs=xs, label="z")
694
695
wtc = WaitTimeCalculator(pmf_z, inverse=False)
696
697
if plot:
698
wtc.PlotPmfs()
699
wtc.MakePlot()
700
701
ete = ElapsedTimeEstimator(wtc, lam, num_passengers)
702
703
if plot:
704
ete.MakePlot()
705
706
return wtc, ete
707
708
709
def RunMixProcess(gap_times, lam=0.0333, num_passengers=15, plot=True):
710
"""Runs the analysis for unknown lambda.
711
712
gap_times: sequence of float
713
lam: arrival rate in passengers per second
714
num_passengers: int number of passengers on the platform
715
plot: boolean, whether to generate plots
716
717
Returns: WaitMixtureEstimator
718
"""
719
global UPPER_BOUND
720
UPPER_BOUND = 1200
721
722
wtc, _ete = RunSimpleProcess(gap_times, lam, num_passengers)
723
724
RandomSeed(20)
725
passenger_data = wtc.GenerateSamplePassengers(lam, n=5)
726
727
total_y = 0
728
total_k2 = 0
729
for k1, y, k2 in passenger_data:
730
print(k1, y/60, k2)
731
total_y += y/60
732
total_k2 += k2
733
print(total_k2, total_y)
734
print('Average arrival rate', total_k2 / total_y)
735
736
are = ArrivalRateEstimator(passenger_data)
737
738
if plot:
739
are.MakePlot()
740
741
wme = WaitMixtureEstimator(wtc, are, num_passengers)
742
743
if plot:
744
wme.MakePlot()
745
746
return wme
747
748
749
def RunLoop(gap_times, nums, lam=0.0333):
750
"""Runs the basic analysis for a range of num_passengers.
751
752
gap_times: sequence of float
753
nums: sequence of values for num_passengers
754
lam: arrival rate in passengers per second
755
756
Returns: WaitMixtureEstimator
757
"""
758
global UPPER_BOUND
759
UPPER_BOUND = 4000
760
761
thinkplot.Clf()
762
763
RandomSeed(18)
764
765
# resample gap_times
766
n = 220
767
cdf_z = thinkbayes2.Cdf(gap_times)
768
sample_z = cdf_z.Sample(n)
769
pmf_z = thinkbayes2.Pmf(sample_z)
770
771
# compute the biased pmf and add some long delays
772
cdf_zp = BiasPmf(pmf_z).MakeCdf()
773
sample_zb = numpy.append(cdf_zp.Sample(n), [1800, 2400, 3000])
774
775
# smooth the distribution of zb
776
pdf_zb = thinkbayes2.EstimatedPdf(sample_zb)
777
xs = MakeRange(low=60)
778
pmf_zb = pdf_zb.MakePmf(xs=xs)
779
780
# unbias the distribution of zb and make wtc
781
pmf_z = UnbiasPmf(pmf_zb)
782
wtc = WaitTimeCalculator(pmf_z)
783
784
probs = []
785
for num_passengers in nums:
786
ete = ElapsedTimeEstimator(wtc, lam, num_passengers)
787
788
# compute the posterior prob of waiting more than 15 minutes
789
cdf_y = ete.pmf_y.MakeCdf()
790
prob = 1 - cdf_y.Prob(900)
791
probs.append(prob)
792
793
# thinkplot.Cdf(ete.pmf_y.MakeCdf(label=str(num_passengers)))
794
795
thinkplot.Plot(nums, probs)
796
thinkplot.Save(root='redline5',
797
xlabel='Num passengers',
798
ylabel='P(y > 15 min)',
799
formats=FORMATS,
800
)
801
802
803
def main(script):
804
RunLoop(OBSERVED_GAP_TIMES, nums=[0, 5, 10, 15, 20, 25, 30, 35])
805
RunMixProcess(OBSERVED_GAP_TIMES)
806
807
808
if __name__ == '__main__':
809
main(*sys.argv)
810
811