Skip to content

Standardize _get_scores() return type across all query strategies#197

Merged
ariapoy merged 1 commit into
ntucllab:masterfrom
CoolJosh0221:master
Apr 8, 2026
Merged

Standardize _get_scores() return type across all query strategies#197
ariapoy merged 1 commit into
ntucllab:masterfrom
CoolJosh0221:master

Conversation

@CoolJosh0221

Copy link
Copy Markdown
Contributor

Standardize _get_scores() to return (np.ndarray, np.ndarray) across all strategies

Motivation

_get_scores() had inconsistent return types across strategies — zip iterators, list(zip(...)), or not implemented at all. This blocks future plans for supporting batch-mode querying and ALBL soft-advice vectors, which need a uniform interface to consume scores from any strategy.

Note: "Soft-advice vectors" = continuous score distributions over the unlabeled pool (vs. the current one-hot hard advice from make_query()), enabling smoother blending in ALBL's Exp4.P bandit.

Changes

Every _get_scores() now returns (entry_ids: np.ndarray, scores: np.ndarray) where higher = more informative. Empty pools return (empty_int_array, empty_float_array). The base class default raises NotImplementedError.

  • 6 strategies updated to new return format (US, BALD, CoreSet, EpsilonUS, InformationDensity, DensityWeightedMeta)
  • 3 strategies added new _get_scores() implementations (QBC, QUIRE, RandomSampling)
  • 1 strategy extracted scores from C extension (HintSVM)
  • 2 strategies raise NotImplementedError (VarianceReduction, ALBL)

Backward compatibility

No public API changes. make_query() still returns int. return_score=True still returns (ask_id, list(zip(...))).

Tests

24 new contract tests in test_get_scores.py covering return types, empty pools, and return_score compatibility. 3 existing test files updated for the new tuple format. 90/90 pass (11 pre-existing sklearn 1.8 multi_class failures are unrelated).

@ariapoy ariapoy left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM.

@ariapoy ariapoy merged commit cac4c1e into ntucllab:master Apr 8, 2026
5 of 8 checks passed
CoolJosh0221 added a commit to CoolJosh0221/libact that referenced this pull request Jul 7, 2026
HintSVM.make_query selected the unlabeled point FARTHEST from the hinted
decision boundary (argmax|f(x)|), the opposite of what the algorithm intends.
Li, Ferng & Lin, "Active Learning with Hinted Support Vector Machine" (ACML
2012, Algorithm 1 Query step / §4.2) query the instance CLOSEST to the query
boundary, i.e. min|f(x)| — standard uncertainty sampling against the hinted
classifier. The old orientation also contradicted the _get_scores contract
("higher = more informative").

The bug dates to the original 2015 port (12305e6); PR ntucllab#197 (cac4c1e) only
repackaged make_query into _get_scores and, misleadingly, documented the
inverted orientation as intended.

Fix: negate the score (scores = -abs(decision_value)) so higher = closer to
the boundary = more informative; make_query keeps argmax and therefore now
selects min|f(x)|. This is an intentional query-behavior change and also
affects strategies that build on HintSVM (ActiveLearningByLearning as a
sub-strategy; DensityWeightedMeta composition).

Tests:
- test_hintsvm.py: add a skip guard so the module collects without the C
  extension; assert argmax(scores) == make_query()'s pick (RNG re-seeded so
  both calls see the same hint pool); assert direction — the on-boundary point
  out-scores deep-in-cluster points and scores are <= 0 (p=0 isolates the
  score direction from the hint-sampling mechanism). Real labels are -1/+1
  because the C extension reserves label 0 as a hint marker.
- test_realdata.py: update the HintSVM golden query sequence, which encoded
  the old (farthest-first) behavior, to the corrected deterministic sequence.
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