Skip to content

Add permutation-column VIP / CV-beta null for the observational relate#468

Merged
kgdunn merged 2 commits into
mainfrom
claude/permutation-column-null-ksh78i
Jul 23, 2026
Merged

Add permutation-column VIP / CV-beta null for the observational relate#468
kgdunn merged 2 commits into
mainfrom
claude/permutation-column-null-ksh78i

Conversation

@kgdunn

@kgdunn kgdunn commented Jul 23, 2026

Copy link
Copy Markdown
Owner

Summary

  • In the p >> n observational relate, even a descriptor with no real relationship earns a non-trivial VIP, so a driver-magnitude threshold cannot come from the fit alone. New process_improve.sensory.permutation_column_null builds one from the data itself.
  • It appends permuted knockoff columns - each a row-shuffled copy of a real descriptor, preserving that column's own marginal (spread, sparsity, support) rather than simulating a distribution - refits the PLS relate over n_iter permutations, and reports, per surviving descriptor, whether its VIP and cross-validated beta clear a high quantile of the knockoff null band (vip_exceeds_null / cv_beta_exceeds_null).
  • Decoupled from the influence gate. It takes an ignore list of descriptor names (validated - an unknown name raises, so a typo fails loudly) that are dropped from the fit entirely, not merely skipped when building knockoffs, so a caller passes the gate-demoted spikes and calibrates only the survivors, undistorted. The knockoff count scales with the block (fraction, a min_knockoffs floor for narrow data, optional cap); n_iter is the permutation count.
  • No simulation: the null is permutations of the real chemistry values. Deterministic given random_state.

Test plan

  • uv run pytest tests/test_sensory.py --no-cov (53 passed). New tests: genuine drivers clear the null while noise columns fall below them; ignore drops named columns from the fit and output; an unknown ignore name raises; identical output for a fixed seed; out-of-range fraction / quantile are rejected.
  • Exercised on the real sparse strawberry data during development: with the gate-demoted spikes passed as ignore, the surviving well-supported chemicals are calibrated against their own permuted-column null.
  • uv run ruff check . and uv run mypy src/process_improve pass.

Checklist

  • Version bumped in pyproject.toml (MINOR: 1.57.0 -> 1.58.0, new public API; CITATION.cff synced)
  • Tests added or updated where relevant
  • ruff check . passes
  • CHANGELOG.md updated

🤖 Generated with Claude Code

https://claude.ai/code/session_018M9u5EpSjHa3mjNaYDJ7qq


Generated by Claude Code

In the p >> n observational relate, even a descriptor with no real relationship
earns a non-trivial VIP, so a magnitude threshold cannot come from the fit alone.
`permutation_column_null` builds one from the data itself: it appends permuted
"knockoff" columns - each a row-shuffled copy of a real descriptor, preserving the
column's own marginal rather than simulating a distribution - refits the PLS relate
over many permutations, and reports, per surviving descriptor, whether its VIP and
cross-validated beta clear a high quantile of the knockoff null band.

The function is decoupled from the influence gate. It takes an `ignore` list of
descriptor names (by name, validated so a typo raises) that are dropped from the fit
entirely - not merely skipped when building knockoffs - so a caller passes the
gate-demoted spikes and calibrates only the survivors, undistorted. The knockoff
count scales with the block (fraction + min floor for narrow data, optional cap) and
`n_iter` sets the permutation count.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018M9u5EpSjHa3mjNaYDJ7qq
@codecov

codecov Bot commented Jul 23, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Fit the augmented block directly and catch both LinAlgError and
NotEnoughVarianceError, so a no-variance (constant) descriptor block degrades to
an ok=False result instead of raising an uncaught error. Add tests for the
degenerate block, the max_knockoffs cap, the too-few-descriptors return, and the
min_knockoffs guard, covering the branches codecov flagged.

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_018M9u5EpSjHa3mjNaYDJ7qq
@kgdunn
kgdunn merged commit a17b81a into main Jul 23, 2026
14 checks passed
@kgdunn
kgdunn deleted the claude/permutation-column-null-ksh78i branch July 23, 2026 10:30
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants