unemployment_linear#

  • Series: lecture-python.myst

  • File: lectures/unemployment_linear.md

  • Audit date: 2026-08-26

  • Corpus snapshot: e25fdf2345

  • Categories audited: writing, math, code, figures, references, links, admonitions (JAX out of scope)

  • Overall score: 8.6 / 10

  • Priority: NONE

Score breakdown#

Category

Score

One-line note

Writing

6/10

qe-writing-005 ×3; qe-writing-003 ×4; qe-writing-001 ×1, +1 more.

Math

8/10

qe-math-010 (proposed) ×1; qe-math-009 ×2.

Code

8.5/10

qe-code-001 ×3.

JAX

out of scope

JAX rules target lecture-jax.

Figures

8.5/10

qe-fig-005 ×2.

References

9/10

qe-ref-001 ×1.

Links

10/10

no mechanical violations detected.

Admonitions

10/10

no mechanical violations detected.

Issues#

Critical#

None found.

High severity#

  • [qe-math-010 (proposed)] — Blackboard \mathbb{P}, \mathbb{E}, \mathbb{V} with braces. Count: 1. Lines: 249. Example: non-blackboard \operatorname{Var}.

Medium severity#

  • [qe-code-001] (reviewer) — Follow PEP8 unless closer to mathematical notation. Count: 3. Lines: 177, 384, 430. Example: the model function’s three prior lines are padded to align their trailing comments and all three overflow because of it: 176-178 give ubar = numpyro.sample("ubar",  dist.Normal(5.5, 2.0))      # Natural rate prior, φ    = ..., σ    = ..., which flake8 (--select=E1,E2,E5,E7,W2,W3,W6,F,C4 --max-line-length=79) reports as E221 twice, E241 twice and E501 three times (83, 82, 81 characters). Dropping the alignment fixes all seven at once. 384 is 83 characters and holds the residual definition on one line, resid = u_monthly[1:] - (med["ubar"] + med["phi"] * (u_monthly[:-1] - med["ubar"])); 430 is 84 and computes resid.std() twice inside one expression, np.exp(-grid**2 / (2 * resid.std()**2)) / (resid.std() * np.sqrt(2 * np.pi)), where the standard deviation is also already available as a name. 194 is the sixth long line (83). Two smaller items: 328 escapes a backslash in a plain string, ax.set_xlabel('$\\phi$'), where an r-string is used nowhere in the file and would be clearer; and exercise 2 draws from the rng created at 507 inside exercise 1 (557), so 553’s “We reuse sim_future and the posterior draws from the previous exercise” understates the dependence - the numbers at 569 also depend on exercise 1 having been run first.

  • [qe-fig-005] — Descriptive figure names for cross-referencing. Count: 2. Lines: 490, 555. Example: code-cell figure without mystnb figure metadata.

  • [qe-math-009] (reviewer) — Choose simplicity in mathematical notation. Count: 2. Lines: 391, 409. Example: 391 stacks a hat on a bar three times in one expression: “\(u_{t+1} - \big(\hat{\bar u} + \hat\phi\,(u_t - \hat{\bar u})\big)\), the model’s one-step-ahead forecast error, with hats denoting the median estimates”. A double accent is hard to read at inline size and hard to distinguish from \(\bar u\) two lines above; naming the plug-in values once (the code calls them med["ubar"] and med["phi"]) and writing the expression in those names would be simpler than decorating the model’s symbols. Second, the skewness display at 409 switches index and introduces an undefined symbol: the whole lecture writes shocks as \(\varepsilon_{t+1}\) (149, 246, 358, 364) and 409 writes \(\frac{\frac1n\sum_i(\varepsilon_i - \bar\varepsilon)^3}{(\frac1n\sum_i(\varepsilon_i-\bar\varepsilon)^2)^{3/2}}\), moving to \(i\) and adding a sample mean \(\bar\varepsilon\) that is never defined - and which the model says is zero (367), a point 402 makes in words (“the residuals already have mean near zero”) without connecting it to the \(\bar\varepsilon\) in the formula.

  • [qe-writing-001] — Use one sentence per paragraph. Count: 1. Lines: 185. Example: 2 sentences in one paragraph.

  • [qe-writing-003] (reviewer) — Maintain logical flow. Count: 4. Lines: 226, 162, 264, 288. Example: the two quantitative claims the lecture is built on are never given as numbers in the text. 226-228 says “The number that matters for us is the posterior for \(\phi\): its mass crowds right up against one. In particular, the mean and median are very close to one, while the standard deviation is very small” - the values exist only inside the print_summary() output at 215, which the reader has to read off, and no figure is anchored to them. 337 then makes an arithmetic claim with neither operand stated: “If the monthly persistence is \(\phi\), then for end-of-year values the persistence is about \(\phi^{12}\), and raising a number near one to the twelfth power pulls it appreciably below one — in line with our annual estimate.” Contrast 436, which does print the skewness. Second, 162-166 insists the prior excludes the endpoint - “We give \(\phi\) a uniform prior on \([0, 1)\) … The upper endpoint is excluded deliberately … This is necessary, as we’ll see below” - and 177 writes dist.Uniform(0.0, 1.0), whose support is the closed interval; the promised justification at 239-288 is also substantive (a random walk would leave the observed band) rather than the technical necessity 166 announces. Third, the random-walk figure is calibrated outside the model it is testing: 253 says “using the observed one-month changes to set the shock size” and 264 sets σ_rw = np.diff(u_monthly).std(), the standard deviation of raw differences, when the posterior draws for sigma are already in hand from 209. Fourth, 288 says “This will become even clearer when we examine annual data”, and the annual section (292-337) argues in the other direction - that the monthly near-unit-root is a frequency artefact, with \(\phi\) well below one at annual frequency - which is a different point from the one 239-286 makes.

  • [qe-writing-005] (reviewer) — Use bold for definitions, italic for emphasis. Count: 3. Lines: 464, 471, 441. Example: 464 bolds two verb phrases to draw a contrast: “considering both a predictive distribution that conditions on fixed parameter values and one that integrates over their posterior uncertainty”. Neither is a definition - the terms actually defined are plug-in and extended at 473-474, correctly bolded and then reused as the code’s own labels at 520 - so 464’s pair is emphasis and wants italic. 471 bolds a single word for the same purpose, “Using the fitted annual model”, distinguishing it from the monthly one. 542 bolds a nine-word clause including maths, “Take the maximum unemployment rate over the next \(H = 8\) years as the statistic”, which is the “overuse of emphasis formatting” the rule’s own check-list names. Against that, 441-443 italicise the three named departures from the Gaussian - heavy-tailed, sharply peaked, right-skewed - two lines after 406 bolds skewness as the definition of the measure of one of them, so the section names four things and weights them two ways.

  • [qe-writing-007] (reviewer) — Use visual elements to enhance understanding. Count: 3. Lines: 337, 343, 490. Example: the one-line bridge at 337 is the lecture’s reconciliation of its two estimates and the figure it sits under does not show it. {numref}`fig-phi-post` (315-331) overlays the monthly and annual posteriors for \(\phi\); adding the implied annual posterior, φ_m**12, is one expression on data already loaded at 322, and it would turn “raising a number near one to the twelfth power pulls it appreciably below one — in line with our annual estimate” from an assertion into the picture’s punchline. Second, the asymmetry the lecture exists to find is described as motion - 343 “unemployment jumps up quickly in recessions and drifts down slowly in recoveries”, 447 “the rare jump up and the long gentle slide down” - and is only ever shown as a third moment: {numref}`fig-resid-skew` (416-437) is a histogram, which by construction throws away the time ordering that the words are about. A plot of resid against time, or of \(\Delta u_t\) with recessions shaded, would show the thing being claimed. Third, the two exercise figures (490-528, 555-570) have no mystnb metadata, so they are the only figures in the file that cannot be named - every body figure is {numref}-referenced (134, 280, 333, 343, 439) and 530-532 and 572-574 have to discuss theirs as “the” plot.

Low severity#

  • [qe-ref-001] — Use correct citation style. Count: 1. Lines: 82. Example: {cite} in narrative flow: ‘of {cite}’.

Strengths#

  • The lecture is organised around one question asked in the first paragraph and answered with a number - “is unemployment a random walk?” (42-44) - and it gives three independent answers that do not agree in the obvious way: the monthly posterior says almost yes (226-230), the escape argument says no (239-286), and the annual posterior says no with reversion (333), with 337 supplying the arithmetic that reconciles the first and third.

  • 239-286 is a genuinely different kind of argument from the estimation around it, and it is the strongest passage in the lecture: rather than testing \(\phi = 1\), it takes the hypothesis seriously, notes that \(\operatorname{Var}(u_t) = t\sigma^2\) grows without bound (249), simulates 400 paths from the observed shock size, and shows them leaving the 3-11% band the series has never left in seventy years (271-284), “including into negative rates”.

  • The convergence diagnostics are explained rather than displayed: 220-224 says what mean, median, the 5%/95% columns, std, n_eff and r_hat each are, what “very close to 1.0” means, and only then concludes “we can trust the draws” - so a reader who has not met NUTS can read the summary table.

  • The residual diagnostic is set up so that only one thing can differ: 400-404 matches the overlaid Gaussian’s standard deviation to the residuals’ own and says why (“the residuals already have mean near zero, so matching the variance makes the mean and the spread agree. Anything left over is then a difference in shape”), and 406-412 then defines the statistic that measures exactly that leftover.

  • 349 states the three steps of the diagnostic before taking them - “state what the model assumes about the shocks, recover them from the data, and compare the two” - and the three subsections at 351, 373 and 396 are those three steps in that order.

  • 450-460 volunteers the objection to its own method (“A Bayesian purist would object that there is no single residual series here”), concedes it, and names the lecture where the fully Bayesian version is done, which is the honest way to use a plug-in diagnostic.

  • Every figure in the body carries both a caption and a name, and every one is actually referenced by {numref} in the prose that follows it (134, 280, 333, 343, 439) - and 15 pulls the GPU admonition in by {include} rather than restating it.

  • 93-98 records the irony that the paper which launched the unit-root literature rejected the unit root for the one series this lecture studies - a {note} that does real work rather than decorating the section.

  • The exercises build on the body rather than restating it: exercise 1 contrasts plug-in against posterior-integrating predictive bands and 487-488 says why the annual model is the right one to do it on (“its persistence \(\phi\) is far less certain than at the monthly frequency, so parameter uncertainty has more to say”), and exercise 2 moves to a path statistic with a decision-relevant reading, \(P(u \geq 7\%\) within eight years\()\).