Commit ffd2e50
Address PR #365 R5 P1 + P3: zero-variance vs NaN; lonely_psu contract; REGISTRY docs
P1 (Methodology — zero computed variance conflated with undefined):
``_jackknife_se_survey`` previously collapsed ``total_variance <= 0.0``
into ``SE=NaN`` with an "every stratum was skipped" warning. That is
correct for the "no stratum contributed" branch (undefined per Rust &
Rao) but wrong for legitimate zero-variance outcomes: full-census FPC
(``fpc[h] == n_h`` → ``f_h = 1`` → ``(1 - f_h) = 0`` zeros every
stratum contribution even when within-stratum dispersion is non-zero)
and exact-zero within-stratum dispersion both give
``total_variance = 0`` by construction, not by "undefined".
Fix: split the terminal branch. Return ``SE=NaN`` only when no stratum
contributed; otherwise return ``SE = sqrt(max(total_variance, 0.0))``.
The ``max(..., 0.0)`` protects against sub-FP-epsilon negatives and
preserves the legitimate zero case at bit precision.
New regression
``test_jackknife_full_design_full_census_fpc_returns_zero_se``:
fits on ``sdid_survey_data_jk_well_formed`` with ``fpc=3`` (n_h=3
per stratum → f_h=1 → zero SE by design). Asserts
``result.se == 0.0`` (not NaN).
P1 (Methodology — lonely_psu silently ignored on jackknife path):
The full-design jackknife always skipped singleton strata (``n_h <
2``) unconditionally, regardless of the user's
``SurveyDesign(lonely_psu=...)`` choice. ``"certainty"`` and
``"adjust"`` were silently degraded to ``"remove"``, which understates
SE when the user intended ``"certainty"`` (equivalent to skip on
jackknife) or flips what should be a zero-variance certainty case
into NaN otherwise.
Fix: validate ``resolved_survey_unit.lonely_psu`` at fit-time on the
survey jackknife path. ``"remove"`` and ``"certainty"`` are both
accepted (they produce the same SE on this path — singleton strata
contribute 0 variance under both, matching canonical Rust & Rao /
``survey::svyjkn`` behavior for JKn). ``"adjust"`` (R's overall-mean
fallback for singleton strata) is rejected with
``NotImplementedError`` and a targeted message pointing to bootstrap
as the unconstrained alternative.
Two regressions:
* ``test_jackknife_full_design_lonely_psu_adjust_raises`` —
verifies the rejection message.
* ``test_jackknife_full_design_lonely_psu_certainty_equivalent_to_remove``
— asserts ``SE_remove == SE_certainty`` at ``rel=1e-14`` on the
well-formed fixture.
P3 (Documentation — REGISTRY lag):
* Placebo feasibility Notes documented Cases B and C but missed Case D
(the exact-count degeneracy guard added in R4). Split the "Fit-time
feasibility guards" paragraph into an explicit 3-case enumeration
(B: zero-control-stratum; C: undersupplied stratum; D: all-exact-
count strata → single allocation).
* ``get_loo_effects_df()`` description still said "Requires
variance_method='jackknife'; raises ValueError otherwise." after R2
taught it to also raise ``NotImplementedError`` on PSU-level survey
jackknife. Rewrote to distinguish unit-level (available) vs PSU-
level (blocked, with pointer to ``result.placebo_effects``).
* Added a Zero-variance-vs-undefined distinction paragraph and a
"lonely_psu contract" paragraph to the jackknife survey Note,
matching the shipped behavior from the two P1 fixes above.
Verification: 93 passed (3 new regressions).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>1 parent f039e2f commit ffd2e50
3 files changed
Lines changed: 158 additions & 5 deletions
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
935 | 935 | | |
936 | 936 | | |
937 | 937 | | |
| 938 | + | |
| 939 | + | |
| 940 | + | |
| 941 | + | |
| 942 | + | |
| 943 | + | |
| 944 | + | |
| 945 | + | |
| 946 | + | |
| 947 | + | |
| 948 | + | |
| 949 | + | |
| 950 | + | |
| 951 | + | |
| 952 | + | |
| 953 | + | |
| 954 | + | |
| 955 | + | |
| 956 | + | |
| 957 | + | |
| 958 | + | |
| 959 | + | |
| 960 | + | |
| 961 | + | |
| 962 | + | |
938 | 963 | | |
939 | 964 | | |
940 | 965 | | |
| |||
2431 | 2456 | | |
2432 | 2457 | | |
2433 | 2458 | | |
2434 | | - | |
| 2459 | + | |
2435 | 2460 | | |
2436 | 2461 | | |
2437 | 2462 | | |
| |||
2443 | 2468 | | |
2444 | 2469 | | |
2445 | 2470 | | |
2446 | | - | |
| 2471 | + | |
| 2472 | + | |
| 2473 | + | |
| 2474 | + | |
| 2475 | + | |
| 2476 | + | |
| 2477 | + | |
| 2478 | + | |
| 2479 | + | |
2447 | 2480 | | |
2448 | 2481 | | |
2449 | 2482 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1585 | 1585 | | |
1586 | 1586 | | |
1587 | 1587 | | |
1588 | | - | |
| 1588 | + | |
| 1589 | + | |
| 1590 | + | |
| 1591 | + | |
| 1592 | + | |
| 1593 | + | |
1589 | 1594 | | |
1590 | 1595 | | |
1591 | 1596 | | |
1592 | | - | |
| 1597 | + | |
1593 | 1598 | | |
1594 | 1599 | | |
1595 | 1600 | | |
| |||
1603 | 1608 | | |
1604 | 1609 | | |
1605 | 1610 | | |
| 1611 | + | |
| 1612 | + | |
| 1613 | + | |
| 1614 | + | |
1606 | 1615 | | |
1607 | 1616 | | |
1608 | 1617 | | |
| |||
1644 | 1653 | | |
1645 | 1654 | | |
1646 | 1655 | | |
1647 | | - | |
| 1656 | + | |
1648 | 1657 | | |
1649 | 1658 | | |
1650 | 1659 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
1161 | 1161 | | |
1162 | 1162 | | |
1163 | 1163 | | |
| 1164 | + | |
| 1165 | + | |
| 1166 | + | |
| 1167 | + | |
| 1168 | + | |
| 1169 | + | |
| 1170 | + | |
| 1171 | + | |
| 1172 | + | |
| 1173 | + | |
| 1174 | + | |
| 1175 | + | |
| 1176 | + | |
| 1177 | + | |
| 1178 | + | |
| 1179 | + | |
| 1180 | + | |
| 1181 | + | |
| 1182 | + | |
| 1183 | + | |
| 1184 | + | |
| 1185 | + | |
| 1186 | + | |
| 1187 | + | |
| 1188 | + | |
| 1189 | + | |
| 1190 | + | |
| 1191 | + | |
| 1192 | + | |
| 1193 | + | |
| 1194 | + | |
| 1195 | + | |
| 1196 | + | |
| 1197 | + | |
| 1198 | + | |
| 1199 | + | |
| 1200 | + | |
| 1201 | + | |
| 1202 | + | |
| 1203 | + | |
| 1204 | + | |
| 1205 | + | |
| 1206 | + | |
| 1207 | + | |
| 1208 | + | |
| 1209 | + | |
| 1210 | + | |
| 1211 | + | |
| 1212 | + | |
| 1213 | + | |
| 1214 | + | |
| 1215 | + | |
| 1216 | + | |
| 1217 | + | |
| 1218 | + | |
| 1219 | + | |
| 1220 | + | |
| 1221 | + | |
| 1222 | + | |
| 1223 | + | |
| 1224 | + | |
| 1225 | + | |
| 1226 | + | |
| 1227 | + | |
| 1228 | + | |
| 1229 | + | |
| 1230 | + | |
| 1231 | + | |
| 1232 | + | |
| 1233 | + | |
| 1234 | + | |
| 1235 | + | |
| 1236 | + | |
| 1237 | + | |
| 1238 | + | |
| 1239 | + | |
| 1240 | + | |
| 1241 | + | |
| 1242 | + | |
| 1243 | + | |
| 1244 | + | |
| 1245 | + | |
| 1246 | + | |
| 1247 | + | |
| 1248 | + | |
| 1249 | + | |
| 1250 | + | |
| 1251 | + | |
| 1252 | + | |
| 1253 | + | |
| 1254 | + | |
| 1255 | + | |
| 1256 | + | |
| 1257 | + | |
| 1258 | + | |
| 1259 | + | |
| 1260 | + | |
| 1261 | + | |
| 1262 | + | |
| 1263 | + | |
| 1264 | + | |
| 1265 | + | |
| 1266 | + | |
| 1267 | + | |
| 1268 | + | |
| 1269 | + | |
| 1270 | + | |
| 1271 | + | |
| 1272 | + | |
| 1273 | + | |
| 1274 | + | |
1164 | 1275 | | |
1165 | 1276 | | |
1166 | 1277 | | |
| |||
0 commit comments