Problem 665234 · easy · Level 06 Heuristics & Optimization

The Likeliest Success Rate

likelihood · log-likelihood · Bernoulli model · grid search · underflow

A basketball coach logs every free throw of a player as 1 (made) or 0 (missed). She models the shots as independent, each one made with the same unknown probability theta, and wants the value of theta that makes the recorded shots most probable.

Write best_rate(outcomes, steps) that tries every candidate theta = i / steps for i = 1, 2, ..., steps - 1 and returns a tuple (theta, loglik): the candidate under which the outcomes are most probable, and the natural logarithm of that probability. If two candidates tie exactly, return the smaller one.

The setup provides shot_log(n, rate, seed), which simulates n free throws of a player whose true success rate is rate. Try multiplying the probabilities of 2000 simulated shots with Run to see what goes wrong.

Examples

Input:  outcomes = [1, 1, 0, 1, 1, 1, 0, 1, 0, 1], steps = 100
Output: (0.7, -6.108643020548935)
Explanation: 7 made and 3 missed. Under theta = 0.7 the probability of this exact
sequence is 0.7**7 * 0.3**3 = 0.00222, whose log is -6.1086; no other candidate
on the grid makes the sequence more probable.

Input:  outcomes = [1, 0, 0], steps = 10
Output: (0.3, -1.917322692203401)
Explanation: the best candidate among 0.1, 0.2, ..., 0.9 is 0.3, close to 1/3.

Constraints

  • 0 <= len(outcomes) <= 10**5, every outcome is 0 or 1
  • 2 <= steps <= 2000
  • floats are compared with a tolerance of 1e-6

Goals

  • Write the log-likelihood of a Bernoulli model for a list of yes/no outcomes
  • Maximise it over a grid of candidate parameters
  • See why sums of logs replace products of probabilities
Starting Python…