Ports the "hard" histogram variant of HistNetQ (from
https://github.com/pglez84/histnetq) into quapy/method/_histnet.py, dropping
that repo's quantificationlib-backed bag generators in favor of QuaPy's own
sampling protocols (UPP by default). Implemented as a BaseQuantifier,
alongside QuaNet, since it trains end-to-end on samples of known prevalence
rather than following the classify-then-aggregate pattern.
- HistNetQ.fit(X, y): resamples training/validation bags from a
LabelledCollection via a configurable protocol (UPP by default; fresh
random bags each training epoch, a fixed reproducible sequence for
validation).
- HistNetQ.fit_from_samples(protocol, val_protocol=None, mix_bags=False):
trains directly from a protocol that already yields bags (e.g. LeQua's
SamplesFromDir), with an optional mixer to synthesize extra
intermediate-prevalence bags from the given ones.
- Aliased in meta.py (torch-optional, mirroring the existing QuaNet guard)
and registered in META_METHODS.
- Adds test_histnetq covering both entry points on binary and multiclass
synthetic data.
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
fit_tr_val's train_test_split had no random_state, so val_split=float
picked a different split every run; occasionally the split produced a
posterior distribution that made abstention's temperature-scaling
L-BFGS optimizer diverge to NaN. Threaded random_state through the
base class and all four calibrator subclasses, and pinned the test to
a seed confirmed stable across repeated runs.
- Add smoke tests covering data/reader.py, method/_threshold_optim.py,
classification/calibration.py, method/confidence.py, and the pure-numpy
helpers in method/_bayesian.py (skipping the jax/stan-dependent model
code itself, consistent with how the aggregative-method registry already
treats it as optional)
- SVMperf: stop creating a tempfile.TemporaryDirectory() just to discard it
immediately for its .name; generate the path directly instead of doing a
pointless create/delete/recreate cycle (cleanup already happens via the
class's own __del__)
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>