Problem 618720 · medium · Level 06 Heuristics & Optimization

Where the Posterior Peaks

conjugate prior · Beta distribution · MAP estimate · posterior mean · maximum likelihood

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 of theta where its density is highest (the MAP estimate). If the highest density is at an end of [0, 1], return 0.0 or 1.0. If there is no single highest point (the flat Beta(1, 1), or a U shape where both ends are infinitely high), return None.
  • mle: total opened divided by total sent over all days so far (None while 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) <= 1000
  • 0 <= opened <= sent for 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
Starting Python…