A newsletter tries a new subject line. Each day it reports (opened, sent): how many of the emails sent that day were opened. The analyst's belief about the open rate theta starts as a Beta(a, b) distribution, with density proportional to theta**(a - 1) * (1 - theta)**(b - 1) on 0 <= theta <= 1, and is updated by Bayes' rule after every day.
Write track_open_rate(a, b, days) that returns one tuple per day, describing the belief after that day's data:
(a_post, b_post, mean, peak, mle)
a_post,b_post: the parameters of the updated Beta distribution,mean: its mean,peak: the value ofthetawhere its density is highest (the MAP estimate). If the highest density is at an end of[0, 1], return0.0or1.0. If there is no single highest point (the flat Beta(1, 1), or a U shape where both ends are infinitely high), returnNone.mle: total opened divided by total sent over all days so far (Nonewhile nothing has been sent).
Examples
Input: a = 1, b = 1, days = [(7, 10), (3, 10)]
Output: [(8, 4, 0.6666666666666666, 0.7, 0.7), (11, 11, 0.5, 0.5, 0.5)]
Explanation: with a flat prior the peak equals the maximum likelihood estimate.
Input: a = 0.5, b = 0.5, days = [(0, 0), (0, 3), (1, 1)]
Output: [(0.5, 0.5, 0.5, None, None), (0.5, 3.5, 0.125, 0.0, 0.0),
(1.5, 3.5, 0.3, 0.16666666666666666, 0.25)]
Explanation: Beta(0.5, 0.5) is U-shaped, so there is no single peak. After three
unopened emails the density is highest at theta = 0.
Constraints
a > 0,b > 0(whole numbers or floats),0 <= len(days) <= 10000 <= opened <= sentfor each day- floats are compared with a tolerance of
1e-6
Goals
- Update a Beta prior with batches of yes/no data in closed form
- Find the peak (MAP) of a Beta posterior, including the cases where it sits at an edge or does not exist
- Compare the MAP estimate, the posterior mean and the maximum likelihood estimate as data accumulates