Likelihood and the maximum likelihood estimator
Likelihood and the maximum likelihood estimator (lesson 5.9.1)
0 of 8 correct
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
How to type answers
- Powers with
^:x^7,2^(1/3),a^-2. - Multiply with
*or by writing side by side:3x^2,2(x+1). ln(x)is the natural log,log(x, 2)is log base 2,eis Euler's number,sqrt(x)is a square root.sin(x),cos(x)andtan(x)take radians; writepifor π andsin(x)^2for sin²x.- Your first answer to each question is saved: it counts towards your score and brings the question back for review.
- Exact answers like
ln(20)/ln(3)are best. Decimals need about 4 significant figures.
Fisher information and standard errors
Fisher information and standard errors (lesson 5.9.2)
0 of 10 correct
- 1.
- 2.
- 3.
- 4.
- 5.
- 6.
- 7.
- 8.
- 9.
- 10.
How to type answers
- Powers with
^:x^7,2^(1/3),a^-2. - Multiply with
*or by writing side by side:3x^2,2(x+1). ln(x)is the natural log,log(x, 2)is log base 2,eis Euler's number,sqrt(x)is a square root.sin(x),cos(x)andtan(x)take radians; writepifor π andsin(x)^2for sin²x.- Your first answer to each question is saved: it counts towards your score and brings the question back for review.
- Exact answers like
ln(20)/ln(3)are best. Decimals need about 4 significant figures.
Coding exercise
Standard errors from the Hessian
Write standard_errors(nll, theta_hat, d=1e-4), as in lesson 5.9.2. nll takes a NumPy array of parameters and returns the negative log-likelihood; theta_hat is its minimiser, a list or array of one or more numbers.
- Build the Hessian of
nllattheta_hatby lesson 4.3.1's central differences with bumpd. - Raise
ValueErrorif the Hessian is not positive definite (lesson 3.7.1): thentheta_hatis not a peak of the likelihood. - Return a NumPy array: the square roots of the diagonal of the inverse Hessian.
The tests use the coin, the waits, the normal and the fitted line of lessons 5.9.1 and 5.9.2. One test has strongly correlated estimates, so 1 over the square root of the diagonal fails. Two more hand you a dip and a saddle.
See the tests
import math
import numpy as np
from scipy.stats import norm, t
def _coin(p):
return -(7 * math.log(p[0]) + 3 * math.log(1 - p[0]))
def test_coin():
"""7 heads in 10 tosses: the standard error of p at 0.7 is about 0.1449"""
se = standard_errors(_coin, [0.7])
expect_close(se, [math.sqrt(0.7 * 0.3 / 10)], what="standard_errors(coin, [0.7])", rel=1e-5)
def test_returns_array():
"""The result is a NumPy array with one entry per parameter"""
se = standard_errors(_coin, [0.7])
assert isinstance(se, np.ndarray), f"expected a NumPy array, got {type(se).__name__}"
expect_equal(se.shape, (1,), what="shape of the result")
def test_waits():
"""Exponential waits 2, 0.5, 1.5, 4, 2: the standard error of the rate 0.5 is about 0.2236"""
waits = np.array([2, 0.5, 1.5, 4, 2])
nll = lambda p: -(len(waits) * math.log(p[0]) - p[0] * waits.sum())
expect_close(standard_errors(nll, [0.5]), [0.5 / math.sqrt(5)], what="standard_errors(waits, [0.5])", rel=1e-5)
def test_normal():
"""A normal fit to 2, 4, 5, 6, 8 at (5, 2): standard errors 2/√5 and 2/√10"""
x = np.array([2, 4, 5, 6, 8.0])
nll = lambda p: -norm.logpdf(x, p[0], p[1]).sum()
expect_close(standard_errors(nll, np.array([5.0, 2.0])), [2 / math.sqrt(5), 2 / math.sqrt(10)], what="standard_errors(normal, [5, 2])", rel=1e-5)
def test_correlated():
"""The line y = 1 + 1.2x with sigma 0.4: standard errors 0.3098 and 0.1265, from the inverse"""
x = np.array([0, 1, 2, 3, 4.0])
y = np.array([1, 2, 4, 4, 6.0])
nll = lambda p: np.sum((y - p[0] - p[1] * x) ** 2) / (2 * 0.4**2)
expect_close(standard_errors(nll, [1.0, 1.2]), [math.sqrt(0.096), math.sqrt(0.016)], what="standard_errors(line, [1, 1.2])", rel=1e-5)
def test_other_bump():
"""A bump of 0.001 gives the coin's answer too"""
expect_close(standard_errors(_coin, [0.7], d=1e-3), [math.sqrt(0.021)], what="standard_errors(coin, [0.7], d=1e-3)", rel=1e-5)
def test_dip():
"""At the dip between two peaks, theta = 0 for the data -3 and 3, ValueError"""
data = np.array([-3.0, 3.0])
nll = lambda p: -t.logpdf(data, 1, p[0]).sum()
try:
standard_errors(nll, [0.0])
except ValueError:
return
raise AssertionError("expected ValueError: at theta = 0 the negative log-likelihood has a maximum, not a minimum")
def test_saddle():
"""At a saddle, x² − y² at (0, 0), ValueError"""
try:
standard_errors(lambda p: p[0] ** 2 - p[1] ** 2, [0.0, 0.0])
except ValueError:
return
raise AssertionError("expected ValueError: x² − y² has a saddle at (0, 0), not a minimum")