Buckets:
| """Write every logbook page from the reproduction outputs. | |
| Pages are markdown; each trackio cell is a `---` separator, a | |
| `<!-- trackio-cell {json} -->` header and a body. | |
| """ | |
| from __future__ import annotations | |
| import json | |
| import os | |
| ROOT = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) | |
| PAGES = os.path.join(ROOT, ".trackio", "logbook", "pages") | |
| BUCKET = "https://huggingface.co/buckets/SabaPivot/repro-semiknockoffs-artifacts" | |
| def cell(meta: dict, body: str) -> str: | |
| return ( | |
| "\n---\n<!-- trackio-cell\n" | |
| + json.dumps(meta) | |
| + "\n-->\n" | |
| + body.strip() | |
| + "\n" | |
| ) | |
| def write(slug: str, heading: str, cells: str) -> None: | |
| path = os.path.join(PAGES, slug, "page.md") | |
| os.makedirs(os.path.dirname(path), exist_ok=True) | |
| with open(path, "w") as f: | |
| f.write(f"# {heading}\n\n" + cells) | |
| print("wrote", path) | |
| # --------------------------------------------------------------- exec summary | |
| EXEC = """ | |
| **Outcome: all six claims reproduce.** Working only from the arXiv PDF, I | |
| re-implemented Semi-knockoffs (Algorithms 1-4 and the Eq. (1) knockoff | |
| threshold) plus an HRT baseline, and tested each theorem where its own | |
| hypotheses hold. With oracle conditional expectations the Wilcoxon p-values are | |
| uniform (KS p = 0.35, 2,000 null p-values, n = 300) and the realised FDR sits at | |
| or below the nominal q at every q on 500 replicates (q = 0.1 -> 0.075, | |
| 0.3 -> 0.287, 0.5 -> 0.486). The train/test split really is dispensable: with | |
| everything estimated on the same n = 300 samples, Semi-knockoffs holds a type-I | |
| error of 0.052 at alpha = 0.05, while the same holdout randomization test run | |
| without a split blows up to 0.953. The two rate theorems fit their predicted | |
| exponents (Thm 4.1: -0.60 measured against -1/2 predicted, R^2 = 0.995; | |
| Thm 4.3: -1.036 measured against the -1.048 predicted from separately measured | |
| a_n and b_n), the power comparison reproduces Figure 4 (SKO 0.990 vs HRT 0.877 | |
| power, +0.113 paired, p = 6.3e-11, with half the type-I error), and the | |
| Wisconsin Breast Cancer type-I estimates match Figure 6 to two decimals on all | |
| three model classes (RF 0.08, NN 0.04, GB 0.02). | |
| **One caveat the paper does not state.** The 5-permutation derandomisation of | |
| Section 5 does raise power as claimed (0.22 -> 0.46 at n = 50, p = 1e-5), but it | |
| also inflates the type-I error (0.059 -> 0.094 in the same setting; 0.22 at 20 | |
| permutations). A global-null control isolates the cause: with *oracle* | |
| nu = rho the derandomised test stays exact (0.048 at 20 permutations), so the | |
| inflation is an estimation effect - averaging over permutations shrinks the | |
| sampling noise but not the rho-hat-versus-nu-hat bias, and it does not vanish | |
| with n. Theorem 3.3 covers the single-permutation Algorithm 1/2 and is not | |
| contradicted; the Rao-Blackwellised variant has no accompanying theory. | |
| ## Scope & cost | |
| | Item | Value | | |
| | --- | --- | | |
| | Scope | 6 / 6 claims reproduced independently: Thm 3.3, Thm 3.4, Thm 4.1, Thm 4.3, Figs 4-5 (Sec 5.1), Fig 6 (Sec 5.2) | | |
| | Hardware | CPU only (shared x86 box, joblib over 100 workers); no GPU, no accelerator, no API key | | |
| | Compute time | ~35 min wall clock for all seven experiment scripts plus figures | | |
| | Cost | $0 | | |
| | Software | Python 3, NumPy 2.2, SciPy 1.15, scikit-learn 1.7, matplotlib. Wisconsin Breast Cancer via `sklearn.datasets.load_breast_cancer` | | |
| | Seeds | master seed 20260725; every replicate uses a derived `numpy.random.default_rng` stream, printed in each script | | |
| | Independence | written from the PDF's Algorithm boxes; the authors' code at <https://github.com/AngelReyero/loss_based_KO> was located but neither read nor executed | | |
| """ | |
| def exec_summary(): | |
| with open(os.path.join(ROOT, "poster", "poster_embed.html")) as f: | |
| embed = f.read().strip() | |
| body = "````html\n" + embed + "\n````" | |
| txt = cell({"type": "markdown", "title": "Executive summary", "pinned": True}, EXEC) | |
| txt += cell( | |
| { | |
| "type": "figure", | |
| "title": "Reproduction poster (poster_embed.html)", | |
| "pinned": True, | |
| "poster": True, | |
| }, | |
| body, | |
| ) | |
| write("executive-summary", "Executive summary", txt) | |
| # ------------------------------------------------------------------- claim 1 | |
| C1_CLAIM = ( | |
| "Semi-knockoffs avoids the train-test data split required by prior " | |
| "conditional-independence testing methods such as HRT while still yielding " | |
| "valid p-values, via nonparametric paired tests requiring only conditional " | |
| "expectations ν_j and ρ_j rather than exact knockoff construction " | |
| "(Theorem 3.3, Section 3.1)." | |
| ) | |
| C1 = f""" | |
| > **Claim (verbatim).** {C1_CLAIM} | |
| ## Verdict: **verified** | |
| ## What Theorem 3.3 actually asserts | |
| Given the *oracle* conditional expectations ν_j = E[X^j | X^-j] and | |
| ρ_j = E[X^j | X^-j, y], the nonparametric paired test of Algorithm 2 returns a | |
| valid p-value. Under H0 conditional independence forces ρ_j = ν_j, so the two | |
| imputed populations are drawn from one law and the paired loss differences are | |
| symmetric. Nothing in the argument needs a held-out sample, and nothing needs the | |
| joint pairwise exchangeability that a genuine model-X knockoff requires. | |
| ## Independent method | |
| Three separate tests, all in `scripts/c1_pvalue_validity.py`. | |
| **A - oracle validity.** Gaussian design X ~ N(0, Σ), Σ_ij = 0.6^|i-j|, p = 50, | |
| y = β'X + ε with support {{0, 1}}. ν_j and ρ_j are computed in **closed form** | |
| from the joint Gaussian law (`gaussian_nu`, `gaussian_rho` in | |
| `scripts/semiknockoffs.py`) - the exact hypothesis of the theorem. 200 replicates | |
| x 10 null coordinates = 2,000 null p-values per configuration, at n = 30, 100, | |
| 300, for the Wilcoxon and sign variants. Uniformity is tested with a one-sample | |
| KS test. | |
| **B - the decisive no-split contrast.** Everything estimated (ridge imputers) on | |
| the same n = 300 sample, a gradient-boosting black box, and four procedures: | |
| SKO-Wcx with the model trained on all n and tested on all n; HRT with model and | |
| sampler fit on all n and tested on all n; HRT with a proper 50/50 split and a | |
| df-corrected residual sampler; HRT with a 50/50 split and the exact Gaussian | |
| conditional sampler. 100 replicates x 12 null features = 1,200 null p-values. | |
| **C - "only conditional expectations, not exact knockoffs".** A heavy-tailed | |
| multivariate-t(3) elliptical design, where the conditional *mean* is still the | |
| same linear map but the conditional law is heteroscedastic and non-Gaussian, so a | |
| Gaussian model-X sampler is mis-specified. 200 replicates x 10 null coordinates. | |
| **Boundary probe.** Algorithms 1-4 say "sample π_j,1 and π_j,2 *permutations*", | |
| whereas the proof in Appendix E.2 uses i.i.d. uniform indices U_1..U_n. Under | |
| permutations the n paired differences are not independent, which the Wilcoxon | |
| signed-rank test formally requires. Both schemes were measured. | |
| ## Numerical result | |
| Oracle Wilcoxon, null p-values (type-I error at α = 0.05, MC s.e. ~0.005): | |
| | n | permutations | i.i.d. draws | KS p (perm) | | |
| | --- | --- | --- | --- | | |
| | 30 | 0.0400 | 0.0400 | 0.0048 | | |
| | 100 | 0.0530 | 0.0545 | 0.036 | | |
| | 300 | **0.0445** | 0.0525 | **0.348** | | |
| The oracle **sign test** is valid but conservative (0.038 at n = 300, mean | |
| p-value 0.547); its KS rejection is pure discreteness, and it rejects less often | |
| than nominal at every level - consistent with the paper's remark that the | |
| Wilcoxon variant is the more powerful one. | |
| Split versus no split, everything estimated (1,200 null p-values): | |
| | procedure | split | type-I @ 0.05 | type-I @ 0.10 | KS p | | |
| | --- | --- | --- | --- | --- | | |
| | **SKO-Wcx** | **none** | **0.0525** | 0.1058 | **0.362** | | |
| | HRT | none | 0.9525 | 0.9667 | < 1e-300 | | |
| | HRT | 50/50 | 0.0842 | 0.1342 | 3.6e-5 | | |
| | HRT, oracle sampler | 50/50 | 0.0408 | 0.0967 | 0.281 | | |
| Heavy-tailed t(3) elliptical design (2,000 null p-values): | |
| | procedure | type-I @ 0.05 | KS p | | |
| | --- | --- | --- | | |
| | **SKO-Wcx, oracle ν (conditional mean only)** | **0.0405** | **0.501** | | |
| | HRT + split + Gaussian knockoff sampler | 0.1300 | 4.2e-22 | | |
| ## Expected value | |
| Valid p-values means P(p ≤ α) ≤ α and, for a continuous statistic, uniformity. | |
| Expected 0.05 at α = 0.05 and a non-significant KS test. Observed 0.0445 | |
| (oracle) and 0.0525 (fully estimated, no split). | |
| ## Limitation | |
| - Theorem 3.3 is stated for oracle ν_j, ρ_j; test A is the faithful test of it. | |
| Test B additionally shows the estimated Algorithm 1 stays valid in this | |
| signal-bearing regime, which the theorem does not itself guarantee. | |
| - Under an adversarial **global null** (y independent of X, so a flexible model | |
| can only memorise noise) the *estimated* Algorithm 1 becomes anti-conservative: | |
| 0.0795 at n = 300, and it does not improve with n (0.0815 at n = 1,000). See | |
| claim 5 - this is the same ρ-hat-versus-ν-hat bias, and it is exactly what | |
| Theorems 4.1 and 4.3 exist to control. | |
| - HRT with a split shows 0.084 rather than 0.05 here because its residual-based | |
| conditional sampler is itself estimated; with the exact Gaussian sampler it | |
| falls to 0.041. That is a sampler-estimation effect, not a defect of HRT, and | |
| it is reported so the power comparison in claim 5 is read fairly. | |
| ## Artifacts | |
| - `scripts/semiknockoffs.py` - Algorithms 1-4, Eq. (1) threshold, HRT, oracle | |
| ν/ρ, data generators | |
| - `scripts/c1_pvalue_validity.py` - this experiment | |
| - `outputs/claim1_pvalue_validity.json` - all raw numbers | |
| - `figs/claim1_pvalue_validity.png` | |
| - Bundle: <{BUCKET}> | |
| """ | |
| # ------------------------------------------------------------------- claim 2 | |
| C2_CLAIM = ( | |
| "Theorem 3.4 establishes that the Semi-knockoffs procedure controls the " | |
| "false discovery rate at level q, i.e. FDR(S_SKO) ≤ q (Theorem 3.4, " | |
| "Section 3.2)." | |
| ) | |
| C2 = f""" | |
| > **Claim (verbatim).** {C2_CLAIM} | |
| ## Verdict: **verified** | |
| ## Independent method | |
| `scripts/c2_fdr.py`. A known ground-truth support, many replicates, and the | |
| realised FDR (mean FDP over replicates) compared with the nominal q on a grid | |
| q ∈ {{0.05, 0.1, 0.2, 0.3, 0.5}}. This is a direct, decisive test: if | |
| Theorem 3.4 is true, FDR ≤ q must hold at finite n, for **every** q, for **any** | |
| model m-hat. | |
| Setting: X ~ N(0, Σ), Σ_ij = 0.6^|i-j|, n = 300, p = 50, support = first 12 | |
| coordinates with β_j ~ U[1, 2], ε ~ N(0, 1). | |
| - **Oracle regime** (Algorithm 3, the exact hypothesis "given ν_j and ρ_j"): | |
| ν_j and ρ_j taken in closed form from the joint Gaussian law. 500 replicates | |
| with a gradient-boosting black box, 500 more with a Lasso black box. | |
| - **Estimated regime** (Algorithm 4): ν-hat, ρ-hat are ridge regressions fitted | |
| on the same n samples. 500 replicates. | |
| - **Boundary probes:** a nonlinear design where the linear imputer is | |
| mis-specified (300 reps); "BH on the Wilcoxon p-values" as the alternative | |
| route the paper says should be worse (300 reps); and the global null with no | |
| signal at all (300 reps). | |
| W^j_SKO = (1/n) Σ_i [ l(m-hat(X~1_i), y_i) - l(m-hat(X~2_i), y_i) ], threshold | |
| T_q from Eq. (1) in its knockoff+ form, S = {{j : W^j ≥ T_q}}. | |
| ## Numerical result | |
| Realised FDR (mean FDP over 500 replicates), 95% half-width in brackets: | |
| | q | oracle + GB | oracle + Lasso | estimated + GB | mis-specified imputer | | |
| | --- | --- | --- | --- | --- | | |
| | 0.05 | 0.0026 (0.0029) | 0.0008 (0.0016) | 0.0026 (0.0029) | 0.0028 (0.0038) | | |
| | 0.10 | **0.0746** (0.0087) | 0.0686 (0.0077) | 0.0759 (0.0085) | 0.0520 (0.0105) | | |
| | 0.20 | **0.1749** (0.0130) | 0.1597 (0.0114) | 0.1969 (0.0138) | 0.1593 (0.0173) | | |
| | 0.30 | **0.2871** (0.0146) | 0.2266 (0.0108) | 0.3034 (0.0152) | 0.2582 (0.0200) | | |
| | 0.50 | **0.4858** (0.0141) | 0.2797 (0.0083) | 0.4950 (0.0135) | 0.4640 (0.0191) | | |
| Power is 1.000 at every q ≥ 0.1 in the oracle and estimated regimes, 0.836-0.958 | |
| under the mis-specified imputer. Under the **global null** (no true signal) the | |
| realised FDR is 0.000 / 0.000 / 0.043 / 0.093 / 0.387 for the five q values - | |
| controlled everywhere, and far below q at small q. | |
| The BH-on-p-values alternative is also controlled but strictly more conservative | |
| (FDR 0.032 / 0.065 / 0.134 / 0.200 / 0.345), matching the paper's Appendix F.5 | |
| statement that the knockoff threshold should be preferred. | |
| ## Expected value | |
| FDR ≤ q at every q. Observed: satisfied in every oracle configuration with | |
| margin. The single value above its nominal level is the estimated-imputer run at | |
| q = 0.30 (0.3034 vs 0.300), which is 0.44 standard errors above q - inside Monte | |
| Carlo error, and outside the theorem's stated hypotheses anyway (Theorem 3.4 is | |
| conditional on the true ν_j, ρ_j). | |
| ## Limitation | |
| - At q = 0.05 with p = 50 the Eq. (1) threshold needs at least 1/q = 20 | |
| discoveries before it can fire; the true support has only 12 members, so the | |
| procedure correctly returns the empty set (power 0.006). This is the standard | |
| knockoff detection floor, not a failure of the theorem. | |
| - 500 replicates give a Monte Carlo s.e. of about 0.007 on the FDR at q = 0.2, so | |
| a violation smaller than ~0.015 would not be detectable here. | |
| - The estimated-imputer column is reported for completeness; Theorem 3.4 does not | |
| cover it (Sections 4.2-4.5 argue it holds approximately). | |
| ## Artifacts | |
| - `scripts/c2_fdr.py`, `outputs/claim2_fdr.json`, `figs/claim2_fdr.png` | |
| - Bundle: <{BUCKET}> | |
| """ | |
| # ------------------------------------------------------------------- claim 3 | |
| C3_CLAIM = ( | |
| "Theorem 4.1 shows that for null (non-relevant) features, regularized " | |
| "empirical risk minimizers trained with and without the feature remain " | |
| "close, with a ‖θ̃^j − θ̂‖₂ ≤ O_P(√(log(1/δ)/n)) bound, giving " | |
| "optimization stability guarantees for regularized models (Theorem 4.1, " | |
| "Section 4.2)." | |
| ) | |
| C3 = f""" | |
| > **Claim (verbatim).** {C3_CLAIM} | |
| ## Verdict: **verified** | |
| ## Independent method | |
| `scripts/c3_stability.py`. R_n(θ) = (1/n) Σ_i l(θ'χ_i, z_i) + λ‖θ‖² as in | |
| Eq. (2); θ-hat is the minimiser over R^p, θ-hat^{{-j}} the minimiser over R^{{p-1}}, | |
| and θ-tilde^j = (0, θ-hat^{{-j}}) re-embedded. (scikit-learn's Ridge minimises | |
| ‖Xw - z‖² + α‖w‖², so α = nλ.) | |
| 1. **Figure 1 reproduction.** z = χβ + ε with β 0.25-sparse in blocks of 5, | |
| n = 300, p = 50, χ ~ N(0, Σ) with Σ_ij = 0.6^|i-j|, noise level ‖χβ‖/2. | |
| Ridge and Lasso, 50 replicates. | |
| 2. **Rate in n.** Fit log Q_{{1-δ}}(‖θ-tilde^j - θ-hat‖₂) = a log n + c over | |
| n ∈ [50, 3200] for null coordinates only; the theorem predicts a = -1/2. | |
| 60 replicates per sample size. | |
| 3. **Rate in δ.** At the largest n, regress the (1-δ)-quantile on | |
| √(log(1/δ)) for δ from 0.5 down to 0.005. | |
| 4. **Boundary probes.** λ swept over {{1e-1, 1e-2, 1e-3, 1e-6}} (the proof needs | |
| λ > 0 for strong convexity but identifies θ* with the *unregularised* | |
| population minimiser via Assumption E.4, so a bias floor of order λ was a | |
| plausible failure mode); and a t_2 design, which breaks the sub-Gaussian | |
| Assumption E.2. | |
| 5. **The quantity the method actually uses.** ν-hat regresses X^j on X^-j and | |
| ρ-hat regresses X^j on (X^-j, y): here the "extra uninformative feature" is y | |
| itself, which is precisely what Section 4.2 invokes. Null versus important j, | |
| and the rate in n. | |
| ## Numerical result | |
| Figure 1 reproduced (n = 300, p = 50, λ = 1e-2, 50 replicates): | |
| | learner | mean, unimportant j | mean, important j | separation | AUC | | |
| | --- | --- | --- | --- | --- | | |
| | Ridge | 0.342 | 1.869 | 5.46x | 0.994 | | |
| | Lasso | 0.315 | 1.874 | 5.95x | 0.994 | | |
| Fitted decay exponents at δ = 0.05 (predicted **-0.50**): | |
| | configuration | fitted exponent | exponent over the last 3 sample sizes | R² | | |
| | --- | --- | --- | --- | | |
| | Ridge λ = 1e-3 | **-0.600** | -0.545 | 0.995 | | |
| | Ridge λ = 1e-2 | -0.588 | -0.551 | 0.997 | | |
| | Ridge λ = 1e-1 | **-0.492** | -0.487 | 0.998 | | |
| | Ridge λ = 1e-6 | -0.601 | -0.545 | 0.995 | | |
| | Lasso λ = 1e-2 | -0.640 | -0.609 | 0.998 | | |
| | Ridge, **t_2 design (E.2 broken)** | -0.683 | -0.577 | **0.569** | | |
| δ-dependence at n = 3,200 (Ridge λ = 1e-3): the quantile is linear in | |
| √(log(1/δ)) with **R² = 0.994**; the log-log exponent on log(1/δ) is +0.72 | |
| rather than +0.50, which is what a linear fit a + b√x with a negative intercept | |
| produces over a finite δ range - still O(√(log(1/δ))). | |
| The ν-hat / ρ-hat coefficients (test 5), Q_0.95 of ‖θ-tilde - θ-hat‖₂: | |
| | n | 50 | 100 | 200 | 400 | 800 | 1600 | 3200 | fitted exponent | | |
| | --- | --- | --- | --- | --- | --- | --- | --- | --- | | |
| | null j | 1.010 | 0.510 | 0.342 | 0.255 | 0.182 | 0.120 | 0.085 | **-0.565** | | |
| | important j | 2.001 | 1.696 | 1.550 | 1.553 | 1.534 | 1.470 | 1.477 | **-0.062** | | |
| ## Expected value | |
| Exponent -1/2 in n, and a √(log(1/δ)) dependence on the confidence level. | |
| Measured -0.49 to -0.60 with R² ≥ 0.995 across regularisation strengths and both | |
| learners, and the δ-scaling fits √(log(1/δ)) at R² = 0.994. | |
| ## Limitation | |
| - The fitted exponents run slightly *steeper* than -1/2 at small λ (-0.60), and | |
| the estimate drifts toward -0.545 over the last three sample sizes, so the | |
| asymptotic slope is consistent with -1/2 but the finite-n fit is not exactly | |
| -0.5. O_P is an upper bound, so a steeper measured decay is not a violation. | |
| - No bias floor was found even at λ = 1e-1 (tail exponent -0.487), so the gap | |
| between the λ-strongly-convex argument and Assumption E.4's unregularised θ* | |
| is not visible at these scales; it may only bite at larger λ. | |
| - Breaking the sub-Gaussian design assumption (t_2) is what degrades the fit - | |
| R² falls from 0.995 to 0.569 at δ = 0.01 - which is the expected behaviour | |
| outside the theorem's hypotheses, but a heavier-tailed sweep would pin the | |
| breakdown more sharply. | |
| - Only the quadratic loss is tested; the paper also verifies the assumptions for | |
| cross-entropy. | |
| ## Artifacts | |
| - `scripts/c3_stability.py`, `outputs/claim3_stability.json`, | |
| `figs/claim3_stability.png` | |
| - Bundle: <{BUCKET}> | |
| """ | |
| # ------------------------------------------------------------------- claim 4 | |
| C4_CLAIM = ( | |
| "Theorem 4.3 provides a double-robustness property: the loss difference " | |
| "between imputed feature distributions decays at a compound rate " | |
| "O_P(a_n b_n) even when both the predictive model and the sampler have " | |
| "estimation error (Theorem 4.3, Section 4.4)." | |
| ) | |
| C4 = f""" | |
| > **Claim (verbatim).** {C4_CLAIM} | |
| ## Verdict: **verified** (for the differentiable m-hat the theorem assumes) | |
| ## Independent method | |
| `scripts/c4_double_robustness.py`. Theorem 4.3 says: for j ∈ H0, with | |
| t ↦ l(t, y) twice differentiable with bounded derivatives, m-hat differentiable | |
| in coordinate j, a_n := ∂_{{x^j}} m-hat and ν-hat - ν = O_P(b_n), | |
| l(m-hat(X~'), y) - l(m-hat(X~), y) = O_P(a_n b_n). | |
| The strategy is to measure a_n and b_n **separately** on the same runs, predict | |
| the compound exponent as their sum, and compare it with the measured decay of the | |
| loss gap. X~ uses the oracle ν and X~' the estimated ν-hat with the *same* | |
| residual index, so the difference isolates the imputer error. | |
| 1. **Figure 3 reproduction.** y = 0.8X¹ + 0.6X² + 0.4X³ + 0.2X⁴ + sin(X¹) + ε, | |
| ε ~ N(0, 0.5), n = 2000, X ~ N(0, Σ) with Σ_ij = 0.5^|i-j|, ν-hat linear, | |
| null coordinate j = 0; Random Forest, Neural Network, Gradient Boosting. | |
| Blue = the semi-knockoff statistic l(m(X~'_1),y) - l(m(X~'_2),y); orange = | |
| l(m(X~'_1),y) - l(m(X~_1),y), which is the doubly-robust quantity. | |
| 2. **Compound-rate fit.** Sweep n ∈ [100, 6400], measure a_n (secant sensitivity | |
| of m-hat in coordinate j), b_n = ‖ν-hat - ν‖₂/√n, and D_n = the 0.9-quantile | |
| of the per-observation |loss gap| (Theorem 4.3 is a pointwise statement, so a | |
| pointwise scale is used rather than an average over i, which would contribute | |
| its own 1/√n). | |
| 3. **Boundary probe / discriminating test.** Repeat for an **important** | |
| coordinate. There a_n is O(1) rather than O_P(n^-1/2), so only b_n survives | |
| and the predicted exponent moves from about -1 to about -1/2. If the measured | |
| exponent tracked b_n alone in both cases, the compound-rate claim would be | |
| falsified. | |
| ## Numerical result | |
| Figure 3 reproduced, n = 2000, 8 replicates, null coordinate j = 0: | |
| | m-hat | sd(blue) | sd(orange) | concentration ratio | | |
| | --- | --- | --- | --- | | |
| | Random Forest | 0.0359 | 0.0059 | **6.1x** | | |
| | Neural Network | 0.3843 | 0.0364 | **10.6x** | | |
| | Gradient Boosting | 0.0336 | 0.0127 | **2.6x** | | |
| Compound-rate fits (exponents in n; "predicted" = fitted a_n exponent + fitted | |
| b_n exponent, measured on the same runs): | |
| | m-hat, coordinate | a_n exp | b_n exp | predicted a_n b_n | measured (Q_0.9) | measured (mean\\|d\\|) | | |
| | --- | --- | --- | --- | --- | --- | | |
| | **linear, null j** | -0.545 | -0.503 | **-1.048** | **-1.036** | -1.032 | | |
| | **linear, important j** | -0.001 | -0.482 | **-0.483** | **-0.496** | -0.502 | | |
| | NN, important j | +0.006 | -0.443 | -0.437 | -0.400 | -0.410 | | |
| | NN, null j | +0.169 | -0.496 | -0.327 | -0.219 | -0.212 | | |
| | RF, null j | -0.067 | -0.496 | -0.563 | -0.387 | -0.412 | | |
| | GB, null j | -0.567 | -0.481 | -1.048 | -0.267 | -0.594 | | |
| ## Expected value | |
| For a linear m-hat and a null coordinate, Remark 4.4 predicts a_n = β-hat^j = | |
| O_P(n^-1/2) and b_n = O_P(n^-1/2), so the compound rate is O_P(1/n): predicted | |
| exponent -1.048, measured **-1.036** (0.012 apart). For an important coordinate | |
| the single-robust rate -1/2 is expected: predicted -0.483, measured **-0.496**. | |
| Both match, and the two cases differ by a factor of √n exactly as the theorem | |
| requires. | |
| ## Limitation | |
| - Theorem 4.3 assumes m-hat is differentiable in coordinate j. Tree ensembles are | |
| piecewise constant, so the derivative is identically zero; a secant sensitivity | |
| at h = 0.25 sd(X^j) is used as a surrogate for a_n on RF and GB. For those | |
| models the predicted and measured exponents differ substantially (GB null: | |
| -1.048 predicted, -0.267 to -0.594 measured), so the quantitative compound rate | |
| is **not** recovered for non-differentiable learners. The paper says as much | |
| ("strict differentiability is not necessary in practice ... we still observe | |
| faster convergence") and the qualitative claim does hold: Figure 3 reproduces | |
| with 2.6-10.6x concentration. | |
| - The neural-network null case is the weakest fit (measured -0.22 against a | |
| predicted -0.33): the fitted a_n exponent is *positive* (+0.169) for | |
| scikit-learn's default MLP, i.e. its sensitivity to the null coordinate does | |
| not shrink at these sample sizes, so the compound-rate mechanism has nothing to | |
| compound. | |
| - The surrogate a_n is a scalar summary of a function-valued sensitivity, so the | |
| "predicted" column carries its own estimation error. | |
| ## Artifacts | |
| - `scripts/c4_double_robustness.py`, `outputs/claim4_double_robustness.json`, | |
| `figs/claim4_double_robustness.png` | |
| - Bundle: <{BUCKET}> | |
| """ | |
| # ------------------------------------------------------------------- claim 5 | |
| C5_CLAIM = ( | |
| "On simulated data with adjacent-feature support, Semi-knockoffs maintains " | |
| "type-I error control while achieving higher power than HRT, and " | |
| "derandomization with 5 permutations under masked correlation further " | |
| "increases power (Figure 4, Figure 5, Section 5.1)." | |
| ) | |
| C5 = f""" | |
| > **Claim (verbatim).** {C5_CLAIM} | |
| ## Verdict: **verified**, with a validity caveat the paper does not report | |
| ## Independent method | |
| `scripts/c5_power_hrt.py`, `scripts/c5b_derandomization.py`, | |
| `scripts/c5c_derand_validity.py`. Both of the paper's settings at its own scale: | |
| n = 300, p = 50, 50 replicates, α = 0.05. | |
| - **Figure 4 - adjacent support.** X ~ N(0, Σ), Σ_ij = 0.6^|i-j|, | |
| y = β'X + ε, the first 0.25p coordinates of β drawn in [1, 2] and the rest | |
| zero, ε ~ N(0, 1). Pre-trained black box: gradient boosting. | |
| - **Figure 5 - masked correlation.** One relevant coordinate l, | |
| y = X_l + 0.5ε₁, and a correlated **null** variable X_{{l-1}} = X_l + 0.5ε₂. | |
| Pre-trained black box: neural network (scikit-learn defaults, which reproduce | |
| the paper's reported R²). | |
| - Methods: HRT (50/50 split, K = 200 draws, df-corrected residual sampler), | |
| SKO-Wcx (Algorithm 1, one permutation, no split), SKO-Wcx-p5 (Rao-Blackwellised | |
| over 5 permutations, no split), and a LOCO-Wilcoxon refit baseline. | |
| - **Derandomisation sweep.** Because the masked setting saturates at power 1.000 | |
| for every method at n = 300, the permutation count is swept over | |
| {{1, 2, 5, 10, 20}} at n ∈ {{50, 75, 100, 150, 300}}, 100 replicates each, to | |
| measure the gain in the non-saturated regime. | |
| - **Validity control.** A clean global null (y drawn independently of X, so every | |
| coordinate is null), with **oracle** ν = ρ and separately with estimated | |
| ν-hat, ρ-hat, sweeping the permutation count. 200 replicates, 2,000 null | |
| p-values per cell. | |
| ## Numerical result | |
| Figure 4, adjacent support, gradient boosting (R² 0.888 no-split / 0.850 split, | |
| against the paper's 0.910 / 0.886): | |
| | method | power | type-I | AUC | | |
| | --- | --- | --- | --- | | |
| | LOCO-Wcx | 0.340 | 0.056 | 0.791 | | |
| | HRT (50/50 split) | 0.877 | 0.071 | 0.964 | | |
| | **SKO-Wcx (no split)** | **0.990** | **0.044** | 0.998 | | |
| | SKO-Wcx-p5 | 1.000 | 0.057 | 1.000 | | |
| Paired over the same 50 replicates: SKO-Wcx - HRT = **+0.1133 power** | |
| (p = 6.3e-11); SKO-Wcx-p5 - SKO-Wcx = +0.0100 (p = 0.013); SKO-Wcx-p5 - HRT = | |
| +0.1233 (p = 2.4e-12). | |
| Figure 5, masked correlation, neural network (R² 0.548 / 0.468, against the | |
| paper's 0.581 / 0.567): power is **1.000 for HRT, SKO-Wcx and SKO-Wcx-p5** - | |
| saturated - with type-I errors 0.089 / 0.049 / 0.069. LOCO-Wcx reaches 0.660. | |
| Derandomisation in the non-saturated regime (masked setting, 100 replicates): | |
| | n | perms=1 | perms=2 | perms=5 | perms=10 | perms=20 | | |
| | --- | --- | --- | --- | --- | --- | | |
| | **power**, n = 50 | 0.220 | 0.340 | **0.460** | 0.560 | 0.600 | | |
| | power, n = 75 | 0.580 | 0.770 | 0.940 | 0.980 | 1.000 | | |
| | power, n = 100 | 0.800 | 0.950 | 0.980 | 1.000 | 1.000 | | |
| | **type-I**, n = 50 | 0.059 | 0.072 | **0.094** | 0.134 | 0.180 | | |
| | type-I, n = 300 | 0.049 | 0.051 | 0.070 | 0.088 | 0.134 | | |
| The n = 50 gain from 5 permutations is +0.240 power, paired p = 9.8e-6. | |
| Global-null control (type-I at α = 0.05, 2,000 null p-values per cell): | |
| | configuration | 1 perm | 2 | 5 | 10 | 20 | | |
| | --- | --- | --- | --- | --- | --- | | |
| | **oracle ν = ρ, n = 100** | 0.048 | 0.044 | 0.037 | 0.044 | 0.040 | | |
| | **oracle ν = ρ, n = 300** | 0.054 | 0.057 | 0.051 | 0.052 | 0.048 | | |
| | estimated, n = 100 | 0.066 | 0.090 | 0.114 | 0.155 | 0.192 | | |
| | estimated, n = 300 | 0.080 | 0.097 | 0.130 | 0.170 | 0.225 | | |
| | estimated, n = 1000 | 0.082 | 0.093 | 0.129 | 0.170 | 0.217 | | |
| ## Expected value | |
| Both halves of the claim reproduce: type-I control (0.044 against a nominal | |
| 0.05) with higher power than HRT (+0.113, p = 6.3e-11) in the adjacent-support | |
| setting, and a clear power gain from 5-permutation derandomisation under masked | |
| correlation (+0.240 at n = 50). | |
| ## Limitation | |
| - **The paper's exact Figure 5 configuration saturates in my reproduction.** At | |
| n = 300 every method reaches power 1.000, so the derandomisation gain is not | |
| measurable there and I had to lower n to expose it. My SKO implementation is | |
| therefore *more* powerful than the paper's in that setting, not less. | |
| - **The derandomised variant is anti-conservative.** The same 5 permutations that | |
| lift power push the type-I error from 0.059 to 0.094 (n = 50) and from 0.049 to | |
| 0.070 (n = 300). The global-null control isolates the cause: with **oracle** | |
| ν = ρ the derandomised test stays exact at every permutation count | |
| (0.048 at 20 permutations, n = 100), so the inflation comes from the | |
| *estimated* ν-hat / ρ-hat. ρ-hat carries one extra predictor (y) fitted on the | |
| same sample, so its residuals are systematically slightly smaller than | |
| ν-hat's; averaging over permutations shrinks the sampling noise by 1/√k but | |
| leaves that bias untouched, and it does not vanish with n (0.129 at n = 1,000 | |
| with 5 permutations). Theorem 3.3 covers the single-permutation Algorithm 1/2 | |
| and is **not** contradicted - the Rao-Blackwellised variant of Section 5 has no | |
| accompanying theory - but the power comparison should be read with this in | |
| mind. | |
| - The global-null design is adversarial: a flexible learner fitted on pure noise | |
| is maximally sensitive to the imputed coordinate. In the signal-bearing | |
| settings the single-permutation test stays valid (0.044-0.052). | |
| - Only the paper's two settings and two model classes were run; VIM comparators | |
| other than LOCO-Wilcoxon (SCPI, SAGE, dCRT) were not reimplemented. | |
| ## Artifacts | |
| - `scripts/c5_power_hrt.py`, `scripts/c5b_derandomization.py`, | |
| `scripts/c5c_derand_validity.py` | |
| - `outputs/claim5_power.json`, `outputs/claim5b_derandomization.json`, | |
| `outputs/claim5c_derand_validity.json` | |
| - `figs/claim5_power.png`, `figs/claim5b_derandomization.png` | |
| - Bundle: <{BUCKET}> | |
| """ | |
| # ------------------------------------------------------------------- claim 6 | |
| C6_CLAIM = ( | |
| "On the Wisconsin Breast Cancer real dataset, Semi-knockoffs is applied " | |
| "across Random Forest, Neural Network, and Gradient Boosting models to " | |
| "demonstrate model-agnostic feature selection (Figure 6, Section 5.2)." | |
| ) | |
| C6 = f""" | |
| > **Claim (verbatim).** {C6_CLAIM} | |
| ## Verdict: **verified** | |
| ## Independent method | |
| `scripts/c6_wdbc.py`. The Wisconsin Diagnostic Breast Cancer set exactly as | |
| described in Appendix F.6: n = 569 patients, p = 30 numeric features, binary | |
| malignant/benign target, loaded from `sklearn.datasets.load_breast_cancer` and | |
| standardised. Because the true support is unknown, an **artificial null feature | |
| correlated at 0.6 with the original inputs** is appended (a normalised random | |
| combination of the standardised columns plus independent noise); its rejection | |
| frequency over seeds estimates the type-I error, which is precisely the | |
| construction the paper uses to annotate Figure 6. | |
| Per model class - Random Forest, Neural Network, Gradient Boosting - and over 50 | |
| seeds: SKO-Wcx (Algorithm 1, no split), SKO-Wcx-p5 (5-permutation | |
| derandomisation), and HRT with a 50/50 split as the split-based comparator, all | |
| at α = 0.05 with the log-loss. The FDR-controlling variant (Algorithm 4 plus the | |
| Eq. (1) threshold) is also run at q ∈ {{0.1, 0.2, 0.3, 0.5}}. Discovery-set | |
| stability across seeds is measured by mean pairwise Jaccard similarity. | |
| ## Numerical result | |
| Discoveries among the 30 real features, and the artificial-null rejection rate | |
| (50 seeds, α = 0.05): | |
| | m-hat | method | discoveries | type-I (ours) | type-I (paper Fig. 6) | | |
| | --- | --- | --- | --- | --- | | |
| | Random Forest | **SKO-Wcx** | 2.42 ± 1.25 | **0.08** | **0.08** | | |
| | Random Forest | SKO-Wcx-p5 | 3.40 ± 1.31 | 0.06 | 0.04 | | |
| | Random Forest | HRT (split) | 5.38 ± 2.11 | 0.04 | 0.04 | | |
| | Neural Network | **SKO-Wcx** | 4.72 ± 1.98 | **0.04** | **0.04** | | |
| | Neural Network | SKO-Wcx-p5 | 7.06 ± 1.58 | 0.08 | 0.06 | | |
| | Neural Network | HRT (split) | 3.78 ± 2.43 | 0.06 | 0.22 | | |
| | Gradient Boosting | **SKO-Wcx** | 1.90 ± 1.15 | **0.02** | **0.02** | | |
| | Gradient Boosting | SKO-Wcx-p5 | 2.66 ± 1.44 | 0.06 | 0.00 | | |
| | Gradient Boosting | HRT (split) | 2.06 ± 1.70 | 0.06 | 0.08 | | |
| In-sample accuracy 1.000 for all three learners; held-out accuracy on the split | |
| half 0.955 (RF) / 0.972 (NN) / 0.950 (GB). | |
| Knockoff-threshold variant (Algorithm 4), mean features selected and | |
| artificial-null selection rate: | |
| | m-hat | q = 0.1 | q = 0.2 | q = 0.3 | q = 0.5 | | |
| | --- | --- | --- | --- | --- | | |
| | Random Forest | 0.00 (0.00) | 0.36 (0.00) | 1.50 (0.06) | 6.30 (0.20) | | |
| | Neural Network | 0.00 (0.00) | 0.48 (0.02) | 1.00 (0.06) | 5.74 (0.28) | | |
| | Gradient Boosting | 0.00 (0.00) | 0.14 (0.00) | 0.90 (0.04) | 4.76 (0.14) | | |
| ## Expected value | |
| The claim is that the procedure applies across all three model classes and makes | |
| discoveries while controlling the error. That reproduces: SKO-Wcx runs unchanged | |
| on RF, NN and GB, makes 1.9-4.7 discoveries per seed, and its | |
| artificial-null rejection rate is **0.08 / 0.04 / 0.02** - identical to the | |
| values printed beside Figure 6 of the paper. The relative ordering of discovery | |
| counts across model classes (NN > RF > GB) also matches the paper's panel scales. | |
| ## Limitation | |
| - The artificial null feature is re-drawn per seed and its exact construction is | |
| not fully specified in the paper (only "correlated at 0.6 with the original | |
| inputs"); I use a normalised random linear combination of the standardised | |
| columns plus independent noise scaled to give correlation 0.6. | |
| - With 50 seeds the type-I estimate has resolution 0.02 and a Monte Carlo s.e. of | |
| about 0.03, so the two-decimal agreement with Figure 6 should not be | |
| over-interpreted. | |
| - **Discovery sets are seed-dependent** (mean pairwise Jaccard 0.06-0.42), so the | |
| paper's stronger statement that Semi-knockoffs shows "consistent numbers of | |
| discoveries, unlike other methods whose results vary significantly with the | |
| random seed" is only partly reproduced: SKO-Wcx-p5 is indeed the most stable | |
| arm (Jaccard 0.21 / 0.42 / 0.11 against HRT's 0.20 / 0.11 / 0.06), but no | |
| feature is rejected in ≥ 80% of seeds by all three model classes. | |
| - The knockoff-threshold variant selects nothing at q = 0.1 with p = 31, because | |
| Eq. (1) needs at least 1/q = 10 discoveries before it can fire - the same | |
| detection floor noted on the claim-2 page. | |
| - The other comparators in Figure 6 (SCPI, SAGE, LOCO-W, dCRT) were not | |
| reimplemented. | |
| ## Artifacts | |
| - `scripts/c6_wdbc.py`, `outputs/claim6_wdbc.json`, `figs/claim6_wdbc.png` | |
| - Bundle: <{BUCKET}> | |
| """ | |
| # ------------------------------------------------------------------- conclusion | |
| CONCL_ART = "semiknockoffs-repro/repro-bundle:v0" | |
| CONCL_MD = f""" | |
| ## Summary | |
| | Claim | Result | Verdict | Key number | | |
| | --- | --- | --- | --- | | |
| | 1 | Thm 3.3 - valid p-values without a split | **verified** | type-I 0.0445 (oracle) / 0.0525 (estimated, no split) vs 0.953 for HRT without a split | | |
| | 2 | Thm 3.4 - FDR(S_SKO) ≤ q | **verified** | realised FDR 0.075 / 0.175 / 0.287 / 0.486 at q = 0.1 / 0.2 / 0.3 / 0.5, 500 replicates | | |
| | 3 | Thm 4.1 - O_P(√(log(1/δ)/n)) stability | **verified** | fitted exponent -0.60 (predicted -0.50), R² = 0.995 | | |
| | 4 | Thm 4.3 - compound rate O_P(a_n b_n) | **verified** | predicted -1.048 from separately measured a_n, b_n; measured -1.036 | | |
| | 5 | Figs 4-5 - power vs HRT, derandomisation | **verified** | +0.113 power over HRT (p = 6.3e-11) at half the type-I error; +0.240 from 5 permutations at n = 50 | | |
| | 6 | Fig 6 - WDBC across RF / NN / GB | **verified** | artificial-null type-I 0.08 / 0.04 / 0.02, matching Figure 6 exactly | | |
| **What the reproduction adds.** Three things the paper does not report. | |
| (i) Running HRT *without* its split drives the type-I error to 0.953, which turns | |
| the paper's motivation from an assertion into a measurement. | |
| (ii) On a heavy-tailed t(3) elliptical design - where a Gaussian model-X sampler | |
| is mis-specified and reaches 0.130 - Semi-knockoffs stays exact at 0.041, because | |
| its exchangeability argument only needs ρ = ν under the null and never the | |
| additive-innovation assumption. | |
| (iii) The 5-permutation derandomisation of Section 5 buys its power gain with | |
| validity: type-I 0.059 -> 0.094 at n = 50, 0.049 -> 0.070 at n = 300, and up to | |
| 0.225 at 20 permutations. A global-null control with oracle ν = ρ stays exact, | |
| so the inflation is an estimation effect - averaging shrinks the noise but not | |
| the ρ-hat-vs-ν-hat bias - and it does not vanish with n. | |
| **Where the reproduction is weakest.** Theorem 4.3's compound rate is recovered | |
| exactly for the differentiable models it assumes, but not quantitatively for tree | |
| ensembles, where the derivative a_n does not exist and a secant surrogate has to | |
| stand in. The paper's own masked-correlation configuration saturates at power | |
| 1.000 in my hands, so the derandomisation gain had to be measured at smaller n. | |
| ## Download the reproduction bundle | |
| Everything is in the HF bucket | |
| **<{BUCKET}>**: | |
| - `scripts/` - `semiknockoffs.py` (Algorithms 1-4, Eq. (1) threshold, HRT, | |
| closed-form oracle ν/ρ, data generators) plus one script per claim | |
| - `outputs/` - the raw JSON for every experiment, and the run logs | |
| - `figs/` - the six claim figures | |
| - `poster/` - `poster.html`, `poster_preview.pdf/png`, `poster_embed.html`, | |
| `GATE_REPORT.json` | |
| ## Rerun | |
| ```bash | |
| pip install numpy scipy scikit-learn matplotlib joblib | |
| python scripts/c1_pvalue_validity.py # Claim 1 (~1 min) | |
| python scripts/c2_fdr.py # Claim 2 (~4 min) | |
| python scripts/c3_stability.py # Claim 3 (~9 min) | |
| python scripts/c4_double_robustness.py # Claim 4 (~12 min) | |
| python scripts/c5_power_hrt.py # Claim 5 (~5 min) | |
| python scripts/c5b_derandomization.py # Claim 5, derandomisation sweep | |
| python scripts/c5c_derand_validity.py # Claim 5, global-null validity control | |
| python scripts/c6_wdbc.py # Claim 6 (~9 min) | |
| python scripts/make_figs.py # all figures | |
| ``` | |
| Every script takes its seeds from the module-level `SEED0 = 20260725` and is | |
| deterministic given the same scikit-learn version. CPU only, $0. | |
| Paper: [arXiv 2601.23124](https://arxiv.org/abs/2601.23124) · | |
| [OpenReview Xf9hJMGwDd](https://openreview.net/forum?id=Xf9hJMGwDd). | |
| Official code exists at | |
| <https://github.com/AngelReyero/loss_based_KO>; it was located but deliberately | |
| neither read nor executed, so this reproduction is independent. | |
| """ | |
| def main(): | |
| exec_summary() | |
| for slug, heading, body in [ | |
| ( | |
| "claim-1-valid-p-values-without-train-test-split-thm-3-3", | |
| "Claim 1: Valid p-values without train-test split (Thm 3.3)", | |
| C1, | |
| ), | |
| ( | |
| "claim-2-fdr-control-at-level-q-thm-3-4", | |
| "Claim 2: FDR control at level q (Thm 3.4)", | |
| C2, | |
| ), | |
| ( | |
| "claim-3-optimization-stability-for-null-features-thm-4-1", | |
| "Claim 3: Optimization stability for null features (Thm 4.1)", | |
| C3, | |
| ), | |
| ( | |
| "claim-4-double-robustness-compound-rate-thm-4-3", | |
| "Claim 4: Double robustness compound rate (Thm 4.3)", | |
| C4, | |
| ), | |
| ( | |
| "claim-5-power-vs-hrt-and-derandomization-sec-5-1", | |
| "Claim 5: Power vs HRT and derandomization (Sec 5.1)", | |
| C5, | |
| ), | |
| ( | |
| "claim-6-wisconsin-breast-cancer-model-agnostic-application-sec-5-2", | |
| "Claim 6: Wisconsin Breast Cancer model-agnostic application (Sec 5.2)", | |
| C6, | |
| ), | |
| ]: | |
| write(slug, heading, cell({"type": "markdown", "title": heading}, body)) | |
| txt = cell( | |
| { | |
| "type": "artifact", | |
| "title": "Reproduction bundle", | |
| "artifact_type": "dataset", | |
| }, | |
| CONCL_ART, | |
| ) | |
| txt += cell({"type": "markdown", "title": "Download & rerun"}, CONCL_MD) | |
| write("conclusion", "Conclusion", txt) | |
| if __name__ == "__main__": | |
| main() | |
Xet Storage Details
- Size:
- 38.9 kB
- Xet hash:
- bab87aa98e010d830fd38666b56a1f89bf16f24dda008c407335843d1d7c2345
·
Xet efficiently stores files, intelligently splitting them into unique chunks and accelerating uploads and downloads. More info.