{"schemaVersion":2,"courseId":"mle","module":{"id":"likelihood","title":"1 · Building likelihoods","summary":"Turn a probability model into an objective for observed data.","stages":[{"type":"read","id":"mle-likelihood-guide","skillIds":["mle.likelihood","mle.score"],"estimatedMinutes":7,"difficulty":"core","title":"Building likelihoods: research guide","html":"<h2>Building likelihoods</h2><p class=\"lead\">Turn a probability model into an objective for observed data.</p><p>A likelihood is the joint density or mass evaluated at the data and viewed as a function of parameters; support and factorization are part of the model.</p><div class=\"callout\"><b>Workflow.</b> Build the joint density or mass as a function of parameters for observed data.</div><p><b>Diagnostic:</b> Inspect support, independence factorization, and constants. The main failure to avoid is an objective that is not the model's likelihood.</p>","prerequisiteStageIds":[]},{"type":"interactive","id":"mle-likelihood-lab","skillIds":["mle.likelihood"],"estimatedMinutes":6,"difficulty":"core","title":"Likelihood construction intuition lab","note":"Set the true rate and sample size, then watch the Poisson log-likelihood curve tighten around its peak (the MLE = sample mean) as n grows.","params":[{"name":"lam","label":"True rate λ","min":0.5,"max":8,"step":0.1,"value":3},{"name":"n","label":"Sample size n","min":20,"max":400,"step":20,"value":100}],"template":"\nimport numpy as np, matplotlib.pyplot as plt\nfrom scipy.special import gammaln\nrng = np.random.default_rng(0)\nn = int({{n}}); lam_true = {{lam}}\nx = rng.poisson(lam_true, n)                     # observed counts (support: 0,1,2,...)\nmle = x.mean()                                   # Poisson MLE = sample mean\ngrid = np.linspace(0.2, max(2*lam_true, 2*mle) + 2, 300)\n# log-likelihood as a FUNCTION of lambda for the fixed observed data\nll = (x[:, None]*np.log(grid[None, :]) - grid[None, :] - gammaln(x+1)[:, None]).sum(0)\nplt.figure(figsize=(6, 3.7))\nplt.plot(grid, ll, color=\"#da9100\", lw=2)\nplt.axvline(mle, color=\"#3a7d44\", ls=\"--\", lw=1.5, label=f\"MLE = {mle:.2f}\")\nplt.axvline(lam_true, color=\"#8a8a8a\", ls=\":\", lw=1.5, label=f\"true λ = {lam_true:.2f}\")\nplt.xlabel(\"λ\"); plt.ylabel(\"log-likelihood  ℓ(λ)\")\nplt.title(\"Poisson log-likelihood over the observed counts\"); plt.legend()\nprint(f\"MLE (sample mean) = {mle:.3f}   true lambda = {lam_true:.3f}\")\nprint(f\"max log-likelihood = {ll.max():.2f}\")\n","prerequisiteStageIds":["mle-likelihood-guide"]},{"type":"code","id":"mle-likelihood-worked","skillIds":["mle.likelihood"],"estimatedMinutes":10,"difficulty":"core","title":"Building likelihoods: worked Python model","note":"Run the reproducible example, then change one assumption and compare the output.","code":"import numpy as np\ny = np.array([1, 0, 1, 1, 0, 1, 1, 1])\ngrid = np.linspace(0.05, 0.95, 181)\nloglike = np.array([(y*np.log(p) + (1-y)*np.log(1-p)).sum() for p in grid])\np_hat = grid[np.argmax(loglike)]\nprint(f\"Grid MLE: {p_hat:.3f}\")\nprint(f\"Sample mean: {y.mean():.3f}\")","prerequisiteStageIds":["mle-likelihood-lab"]},{"type":"codechallenge","id":"mle-likelihood-challenge","skillIds":["mle.likelihood"],"estimatedMinutes":12,"difficulty":"core","title":"Likelihood construction code challenge","note":"Compute the Bernoulli log-likelihood over the grid and save the maximizing probability as p_hat.","starter":"import numpy as np\ny = np.array([1, 1, 0, 1, 0, 1])\ngrid = np.linspace(0.05, 0.95, 181)\nloglike = ...\np_hat = ...","tests":"expected = np.array([(y*np.log(p)+(1-y)*np.log(1-p)).sum() for p in grid])\nassert np.allclose(loglike, expected)\nassert np.isclose(p_hat, grid[np.argmax(expected)])\nprint(\"grader: likelihood and maximizer are correct\")","hints":["Each observation contributes y log(p)+(1-y) log(1-p).","Evaluate every grid value, then use argmax."],"success":"The numerical result and the likelihood construction workflow both pass the grader.","prerequisiteStageIds":["mle-likelihood-worked"],"variantId":"mle-likelihood-challenge-core"},{"type":"case","id":"mle-likelihood-case","skillIds":["mle.score"],"estimatedMinutes":8,"difficulty":"core","title":"Score equations: model decision","note":"A team is about to report results without checking gradient magnitude and parameter constraints.","steps":[{"prompt":"What is the best next action?","choices":["Differentiate the log-likelihood and interpret zero score at an interior optimum.","Increase decimal precision and report immediately.","Drop observations until the preferred coefficient appears."],"answer":0,"explain":"The defensible workflow is to differentiate the log-likelihood and interpret zero score at an interior optimum."},{"prompt":"Which risk should the final report address explicitly?","choices":["Only whether the sample mean is positive.","declaring convergence while the score remains large","Whether every coefficient has the same sign."],"answer":1,"explain":"The relevant failure mode is declaring convergence while the score remains large."}],"prerequisiteStageIds":["mle-likelihood-challenge"],"variantId":"mle-likelihood-case-core"},{"type":"match","id":"mle-likelihood-match","skillIds":["mle.score"],"estimatedMinutes":7,"difficulty":"core","title":"Score equations: evidence map","note":"Match each research role to the course-specific evidence.","pairs":[{"left":"Good practice","right":"Differentiate the log-likelihood and interpret zero score at an interior optimum."},{"left":"Diagnostic evidence","right":"gradient magnitude and parameter constraints"},{"left":"Failure to guard against","right":"declaring convergence while the score remains large"}],"prerequisiteStageIds":["mle-likelihood-case"],"variantId":"mle-likelihood-match-core"}]}}
