Skip to content

feat: ranking and filtering for biolink:statistical_significance_qualifier - #135

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

feat: ranking and filtering for biolink:statistical_significance_qualifier#135
SkyeAv wants to merge 4 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 and an edge-level significance filter for biolink:statistical_significance_qualifier (biolink/biolink-model#1766) across all Shepherd ARAs, modeled on the equivalent ARAX implementation (RTXteam/RTX#2859). Closes #134.

Shared module

  • shepherd_utils/statistical_significance_qualifier.py (NEW): single source of truth for SIGNIFICANCE_BAND_SCORES (0.70…0.0), SIGNIFICANCE_ORDINAL (4…0), SIGNIFICANCE_SOURCE_WEIGHT (0.5), and get_statistical_significance(edge) — a qualifiers-only lookup that strips any biolink: prefix. Reused by all three consumers 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).

Filtering — filter_edges_by_statistical_significance

  • shepherd_utils/shared.py: filter_edges_by_statistical_significance(message, minimum_significance, logger) — ordinal edge removal (edges explicitly below threshold removed; qualifier-less kept), with analysis/result pruning to keep TRAPI valid. Downstream filter_kgraph_orphans removes orphaned nodes.
  • workers/filter_edges_by_statistical_significance/ (NEW): super-thin async worker (inline, no process pool — mirrors filter_kgraph_orphans). Reads minimum_significance from the nested parameters dict (the older filter_*_top_n workers read flat keys and silently use defaults; this one honors the parameter).
  • compose.yml: service registered, mirroring filter_kgraph_orphans.

Workflow wiring

  • workers/aragorn/worker.py + workers/bte/worker.py: filter inserted after aragorn.score, before sort_results_score, in all four lookup branches (two per ARA). Pathfinder branches untouched.
  • Default minimum_significance=suggestive: removes only edges explicitly labeled not_significant; qualifier-less edges kept.

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; filtering removes only explicitly-labeled edges.
  • 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 filter removes 0 edges today and auto-activates when qualifier data starts flowing.

Testing

  • pytest tests/unit/ -q511 passed (24 new tests: 7 shared-helper, 4 aragorn_score, 5 arax_rank, 8 filter).
  • 3 existing workflow-assertion tests updated to include the new filter op.

SkyeAv added 4 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
…orn + BTE

New filter infrastructure (shepherd#134):
- shepherd_utils/shared.py: filter_edges_by_statistical_significance()
  ordinal edge removal, qualifier-less edges kept, result pruning
- workers/filter_edges_by_statistical_significance/: super-thin worker
  (async, inline, mirrors filter_kgraph_orphans)
- compose.yml: service registration

Wired into Aragorn + BTE lookup workflows (both branches each) with
minimum_significance=suggestive (removes only not_significant edges).
Inert until retriever#197 ships qualifier-bearing edges.

Updated 3 existing workflow-assertion tests.
Tests: 511/511 passing (8 new filter tests).

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