PyOD v3.5.1
Patch release with bug fixes across LUNAR, DIF, SOS, SUOD, LOF, and the GAAL family, plus the v3.5.0 follow-on work and the NSF funding acknowledgment.
Bug fixes
- LUNAR (#502):
LUNAR.__init__previously defaulted to a single sharedMinMaxScaler()instance, so two LUNAR instances with different feature dimensions invalidated each other's predict path. Default is nowscaler=None, materialized to a freshMinMaxScalerper fit via_resolve_scaler(). User-supplied scalers are deep-copied.Falsedisables scaling entirely. The fitted scaler lives onself.scaler_sosklearn.base.clone()round-trips. Thanks to @jbbqqf for the fix. - DIF (#546):
DIF.fitdouble-normalized: it min-max-scaledX, then calledself.decision_function(X)on the already-scaled data, anddecision_functionre-scales internally.decision_scores_anddecision_function(X_train)now match. Thanks to @jbbqqf. - SUOD (#640): module import no longer print-then-crashes when the optional
suodpackage is absent; the actionableImportError("Install it withpip install suod") now fires only whenSUOD()is constructed. Thanks to @jbbqqf. - LOF (#638): class docstring now correctly states
novelty=Trueas the PyOD default. PyOD'sBaseDetectorcontract is fit-then-predict on unseen data, which scikit-learn'sLocalOutlierFactoronly allows in novelty mode; the code default has beenTruefor years but the docstring claimedFalse. Regression test pins both theinspect.signaturedefault and the docstring substring. Thanks to @jbbqqf. - GAAL family (#660):
pyod/models/gaal_base.pyprint-then-crash optional-torch handling replaced with a guarded import and an actionableImportError. Follow-up extends the same fix topyod/models/mo_gaal.py,pyod/models/so_gaal.py, andpyod/models/so_gaal_new.py, so user-visible imports likefrom pyod.models.mo_gaal import MO_GAALno longer print-then-crash when torch is missing. All four GAAL files now raise the unified message pointing atpip install pyod[torch]orpip install torch. Thanks to @tuanaiseo for the initial PR.
Performance
- SOS (#635):
_get_perplexityinner-loop reductions usendarray.sum()directly. Numerical equivalence test asserts bit-exact match against the previousnp.sumform. Thanks to @jbbqqf.
Funding
PyOD is now supported in part by the U.S. National Science Foundation under Award No. 2346158, "NSF POSE: Phase II: OpenAD: An Integrated Open-Source Ecosystem for Anomaly Detection." See the Acknowledgments section in the README for the full attribution.
Tests
6 new regression tests added (1 each in test_lof, test_dif, test_sos, test_suod; 2 in test_lunar).
Migration
No breaking API changes. No deprecated APIs removed.
Acknowledgments
External contributors this release: @jbbqqf (5 PRs) and @tuanaiseo (1 PR).