Skip to content

feat(scoring): add rich selectivity scorer from evidence-identified features - #130

Merged
cschanhniem merged 1 commit into
mainfrom
agent/oamp-loop-20260703i
Jul 3, 2026
Merged

cschanhniem merged 1 commit into
mainfrom
agent/oamp-loop-20260703i

Conversation

@cschanhniem

Copy link
Copy Markdown
Collaborator

Summary

The feature decomposition benchmark (v0.5.15, PR #129) identified 8 statistically significant features for selective_vs_hemolytic discrimination, but the old selectivity_proxy (charge + GRAVY) used only 2. This PR builds a composite selectivity scorer from the evidence — combining all 8 significant features, weighted by detection AUROC.

Key Result

Scorer Detection AUROC CI 95% Significant?
rich_selectivity 0.7138 0.6266-0.7951 YES
selectivity_proxy (old) 0.5744 0.4954-0.6558 Marginal
hemolysis_risk 0.5650 0.4664-0.6601 NO
expert_composite 0.5459 0.4562-0.6305 NO
safety 0.5116 0.4321-0.5954 NO
ensemble 0.4201 0.3335-0.5067 NO (anti-signal)

The rich selectivity scorer is the first pipeline score with statistically significant hemolysis detection on the expanded n=179 benchmark (CI lower bound 0.6266 > 0.5).

Honest Limitations

  • Does NOT triage AMP-vs-decoy correctly (selective_vs_decoy = 0.19). Designed for within-AMP selectivity only; must be combined with an activity gate for candidate selection.
  • Individual feature AUROCs are weak (0.59-0.67); the composite CI is wide (0.63-0.80).
  • Normalisation thresholds are empirical and may not generalise beyond the reference set.
  • Does not model 3D structure, oligomeric state, or membrane curvature.
  • This is a triage signal, NOT a hemolysis predictor. Wet-lab assay remains mandatory.

Changes

  • scoring/selectivity_rich.py: composite scorer with full component breakdown
  • benchmark/retrospective.py: integrated into selectivity benchmark with rich_selectivity_verdict
  • benchmark/triage.py: integrated into standard and strict triage benchmarks
  • benchmark/metrics_snapshot.py: selectivity snapshot expanded with per_score_auroc and verdict
  • cli/commands/benchmark.py: selectivity bench summary includes rich selectivity verdict
  • tests/test_selectivity_rich.py: 18 tests covering scoring, breakdown, and benchmark integration
  • outputs/metrics_snapshot.json: regenerated
  • Docs updated: METRICS_CURRENT.md, ROADMAP.md, ARCHITECTURE.md

Verification

  • uv run pytest -q: 1557 passed, 7 skipped (up from 1539)
  • uv run ruff check src tests: clean
  • git diff --check: clean
  • make metrics-snapshot: regenerated with rich selectivity results
  • Pre-push hook: passed

…eatures

The feature decomposition benchmark (v0.5.15) identified 8 statistically
significant features for selective_vs_hemolytic discrimination, but the
old selectivity_proxy (charge + GRAVY) used only 2. This adds a composite
selectivity scorer combining all 8 significant features, weighted by
detection AUROC.

Key result: rich selectivity detection AUROC=0.7138 (CI 0.6266-0.7951) on
n=179 (54 hemolytic vs 125 selective) — first pipeline score with CI
excluding 0.5. Old selectivity_proxy=0.5744 (CI 0.4954-0.6558).

Honest limitation: does NOT triage AMP-vs-decoy (selective_vs_decoy=0.19);
designed for within-AMP selectivity only. Must be combined with an activity
gate for candidate selection.

Changes:
- scoring/selectivity_rich.py: composite scorer with full breakdown
- benchmark/retrospective.py: integrated into selectivity benchmark
- benchmark/triage.py: integrated into standard and strict triage
- benchmark/metrics_snapshot.py: expanded selectivity snapshot
- cli/commands/benchmark.py: selectivity verdict in CLI summary
- tests/test_selectivity_rich.py: 18 tests
- docs updated (METRICS_CURRENT, ROADMAP, ARCHITECTURE)
@cschanhniem
cschanhniem merged commit 430131d into main Jul 3, 2026
1 check passed
@cschanhniem
cschanhniem deleted the agent/oamp-loop-20260703i branch July 3, 2026 10:21
cschanhniem added a commit that referenced this pull request Jul 3, 2026
… composite, and pilot selection (#131)

The rich selectivity scorer (v0.5.16, PR #130) was benchmarked and proven
significant (detection AUROC=0.7138, CI 0.63-0.80) but was not connected to
any production path where candidate selection actually happens. This PR wires
it into pipeline scoring, expert composite, pilot priority, pilot panel
report, and evidence certificates.

Changes:
- pipeline.py: rich_selectivity computed for every candidate in raw_scores
- scoring/expert.py: rich_selectivity replaces hemolysis_safety (not significant)
  as expert hemolysis-risk component (weight 0.10); old proxy stays as
  activity-ranking selectivity component (weight 0.20)
- selection/pilot.py: pilot_priority uses rich_selectivity with fallback
- reports/pilot_panel.py: rich_selectivity column added to CSV and markdown
- benchmark/retrospective.py: expert ablation uses rich_selectivity component
- tests/test_rich_selectivity_integration.py: 14 integration tests

Expert AUROC drops 0.7119 -> 0.7097 (-0.0022) on AMP-vs-decoy. Acceptable
tradeoff: expert now includes a significant hemolysis detector instead of
a non-significant one.

Constraint: wet-lab hemolysis assay remains mandatory; computational selectivity scores are triage signals only, not biological proof.
Confidence: high - rich selectivity detection AUROC=0.7138 (CI 0.63-0.80, significant); integration verified by 1571 passing tests.
Tested: uv run pytest -q (1571 passed, 7 skipped), ruff check (clean), git diff --check (clean), make metrics-snapshot.

Co-authored-by: OmX <omx@oh-my-codex.dev>
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.

1 participant