Skip to content

feat: ranking for biolink:statistical_significance_qualifier - #135

Open
SkyeAv wants to merge 5 commits into
BioPack-team:mainfrom
SkyeAv:feat/implement-ranking-logic-for-the-statistical-significance-qualifier
Open

feat: ranking for biolink:statistical_significance_qualifier#135
SkyeAv wants to merge 5 commits into
BioPack-team:mainfrom
SkyeAv:feat/implement-ranking-logic-for-the-statistical-significance-qualifier

Conversation

@SkyeAv

@SkyeAv SkyeAv commented Jul 30, 2026

Copy link
Copy Markdown

Adds ranking boosts for biolink:statistical_significance_qualifier (biolink/biolink-model#1766) across all Shepherd ARAs, modeled on the equivalent ARAX implementation (RTXteam/RTX#2859). Closes #134.

Note: the Shepherd-side edge filter from earlier revisions of this PR was removed per #136 — implicit filtering for this qualifier belongs in Gandalf, not Shepherd; Shepherd ranks/scores only. The TRAPI override standard for the default significance cutoff is coordinated in BioPack-team/retriever#198; Gandalf-side filtering and the Retriever pass-through (retriever#197) are tracked in their respective repos.

Shared module

  • shepherd_utils/statistical_significance_qualifier.py (NEW): single source of truth for SIGNIFICANCE_BAND_SCORES (0.70…0.0), SIGNIFICANCE_SOURCE_WEIGHT (0.5), and get_statistical_significance(edge) — a qualifiers-only lookup that strips any biolink: prefix. Reused by both rankers below.

Ranking — aragorn_score (Aragorn + BTE)

  • workers/aragorn_score/worker.py: extracts the qualifier in get_edge_values() via the shared helper (the attribute loop only walks edge["attributes"]; the qualifier lives in edge["qualifiers"]). Adds it as a scored property feeding the graph-Laplacian: band_score × 0.5 → admittance -1/log(weight). Max effective weight 0.35 → bounded boost.
  • Covers both ARAs: aragorn_score is the shared Aragorn + BTE ranker (both workflows run aragorn.score); one change updates both. There is no separate BTE ranker.
  • No penalty: not_significant and qualifier-less edges are unchanged (property_w > 0 guard, also avoids log(0)).

Ranking — arax_rank (ARAX dict port)

  • workers/arax_rank/ranker.py: categorical-bypass injection in _calculate_edge_confidence() — the qualifier is looked up separately from the numeric attribute normalizer (the enum string would otherwise hit float()ValueError). Appends band_score × SIGNIFICANCE_SOURCE_WEIGHT to edge_attribute_score_list. Works even for attribute-less edges (injected at method level, not nested inside if edge.get("attributes")).
  • Mirrors RTX post-refactor: trust weight is a standalone constant, not in known_attributes_to_trust (RTX moved it out in the same refactor).

Design

  • Qualifier-only placement: reads edge["qualifiers"] exclusively — the qualifier is_a: statement_qualifier, so BMT/Retriever route it there. Matches ARAX (qualifier-only as of RTX#2859; its defensive edge.attributes lookup was removed). A one-line fallback in the shared helper covers a KP ever sending it as an attribute.
  • No penalty for qualifier-less edges: rollout is incremental across KGs; penalizing non-adopters would be unfair. Ranking is boost-only.
  • Conservative heuristics: band scores (0.70…0.0) and trust (0.5) match RTX exactly. These are starting points, not empirically validated. Deferred: revisit post-rollout.
  • Deferred: significance-aware path scoring in score_paths (currently purely structural); edge.attributes fallback; per-ARA threshold tuning.
  • Inert until retriever#197 ships: no edges carry the qualifier yet, so the boost applies to zero edges today and auto-activates when qualifier data starts flowing.

Testing

  • Full CI-equivalent suite: tox (py312 + coverage envs) → both envs OK, 502 passed (down from 511 with the filter: 8 filter tests removed with the feature, 1 ordinal-table test removed with the now-dead SIGNIFICANCE_ORDINAL constant).
  • Unit suite: pytest tests/unit -q502 passed, 9 warnings.
  • Targeted qualifier/ranker tests: pytest tests/unit -k "significance or arax_rank or aragorn_score" -v74 passed, 428 deselected (15 new tests: 6 shared-helper, 4 aragorn_score, 5 arax_rank).
  • Coverage (tox coverage env, .coveragerc, branch coverage; gate 10%): total 56.66%; touched files — statistical_significance_qualifier.py 95%, aragorn_score/worker.py 93%, aragorn/worker.py / bte/worker.py 73% each, shared.py 79%, arax_rank/ranker.py 23% (large legacy port file; qualifier path covered by the targeted tests).
  • Verification: git grep filter_edges_by_statistical_significance / git grep SIGNIFICANCE_ORDINAL / git grep minimum_significance0 hits; compose.yml YAML parse valid; black --check clean on the touched files.

SkyeAv added 3 commits July 30, 2026 10:25
New shepherd_utils/statistical_significance_qualifier.py module with:
- SIGNIFICANCE_BAND_SCORES / SIGNIFICANCE_ORDINAL tables (biolink#1766)
- SIGNIFICANCE_SOURCE_WEIGHT (0.5, conservative, matches RTX)
- get_statistical_significance(edge): qualifiers-only lookup

Shared by aragorn_score, arax_rank, and the filter worker.
Tests: 7/7 passing.

Refs: shepherd#134
…ranker

aragorn_score/worker.py (shared Aragorn + BTE ranker):
- Extract qualifier via get_statistical_significance() in get_edge_values()
- Add as scored property: band_score x 0.5 trust -> admittance feed
- not_significant / qualifier-less edges unchanged (no penalty)

Tests: 35/35 passing (4 new).

Refs: shepherd#134
arax_rank/ranker.py (dict-based port of RTX ARAX_ranker.py):
- Categorical bypass: qualifier looked up separately from attributes
- Additive score: band_score x SIGNIFICANCE_SOURCE_WEIGHT (0.5)
- Injected at method level (works even for attribute-less edges)
- Mirrors RTX post-refactor: standalone trust weight, not in
  known_attributes_to_trust

Tests: 5/5 passing.

Refs: shepherd#134
@SkyeAv

SkyeAv commented Aug 6, 2026

Copy link
Copy Markdown
Author

Decisions on where statistical significance filtering lives (Gandalf, not Shepherd) are now recorded in #136 — filtering portion of this PR to be removed per that issue.

The Shepherd-side edge filter was removed per shepherd#136 (filtering
belongs in Gandalf). Update the shared helper module so it no longer
references the filter_edges_by_statistical_significance worker:
- module docstring: shared by aragorn_score + arax_rank (ranking) only
- SIGNIFICANCE_ORDINAL comment: describe the ordinal scale neutrally
  (table kept as part of the qualifier vocabulary)

Refs: shepherd#136
@SkyeAv
SkyeAv force-pushed the feat/implement-ranking-logic-for-the-statistical-significance-qualifier branch from 2a1e242 to ab97759 Compare August 7, 2026 19:33
@SkyeAv SkyeAv changed the title feat: ranking and filtering for biolink:statistical_significance_qualifier feat: ranking for biolink:statistical_significance_qualifier Aug 7, 2026
@SkyeAv

SkyeAv commented Aug 7, 2026

Copy link
Copy Markdown
Author

Removed the Shepherd-side edge filter per #136 (filtering belongs in Gandalf). The branch was rewritten to drop the filter commit entirely, so this PR now contains only the ranking/scoring work (aragorn_score + arax_rank) and the shared qualifier helpers.

…-team#136

The ordinal table existed solely for the filter_edges_by_statistical_significance
feature removed per BioPack-team#136 (filtering belongs in Gandalf, not Shepherd). Drop the
now-dead constant and its test assertions; ranking/scoring only ever used
SIGNIFICANCE_BAND_SCORES and SIGNIFICANCE_SOURCE_WEIGHT.

Refs: shepherd#136
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.

feat: ranking & filtering support for biolink:statistical_significance_qualifier

1 participant