Skip to content

v3.6.4

Latest

Choose a tag to compare

@yzhao062 yzhao062 released this 02 Aug 12:30
3d0169a

PyOD 3.6.4

A documentation-accuracy release. No runtime behavior changes: an executable-AST comparison confirms the 43 touched model modules differ only in docstrings.

An audit compared every constructor signature against its numpydoc block, attempted all 72 example scripts, and built the Sphinx site. What it found was mostly not wrong prose but documentation that had quietly drifted away from the code.

Documented parameters that did not exist

Seven documented constructor parameters raise TypeError when passed. A user following the docs got an error, and the error looked like their mistake:

GMM(verbose=0)                    # TypeError
LUNAR(n_neighbors=5)              # TypeError - the real keyword is n_neighbours
RGraph(random_state=42)           # TypeError
SUOD(cost_forecast_loc_fit=...)   # TypeError

These entries are removed, or renamed to the real keyword where one exists. LUNAR's entry keeps a note about the British spelling so a search for n_neighbors still lands somewhere useful.

Documented defaults that disagreed with the signature

Roughly fourteen, including ABOD.n_neighbors (documented 10, actually 5), ALAD.epochs (500 / 200), ALAD.preprocessing (True / False), AnoGAN.learning_rate_query (0.001 / 0.01), RGraph.transition_steps (20 / 10), and DIF.hidden_neurons, documented as [64, 32] while the constructor substitutes [500, 100] for the None default.

Also corrected: labels_ was typed as int in BaseDetector and in every detector that copied the wording, when it is a numpy array of shape (n_samples,); and XGBOD.labels_ claimed threshold_ is applied to decision_scores_ when fit() never sets threshold_.

Sphinx: 310 warnings to 41

sphinx.ext.napoleon had never been enabled, so every numpydoc Parameters and Attributes heading was parsed as an RST section title rather than a field list. A full build went from 310 warnings and 242 class="problematic" spans to 41 and 5, and the :attr: links for decision_scores_ and labels_ — the two attributes every user touches after fit() — resolve for the first time.

Enabling the parser also exposed five docstrings it could not read, which had been inert text until now: AnoGAN emitted 1 of its 16 parameters, RGraph 5 of 16, DIF produced 30 fields for an 11-parameter constructor, XGBOD turned a commented-out block into four bogus parameter names, and the SO_GAAL in so_gaal_new.py had an entirely empty Parameters section. All five are repaired, and a sweep over all 62 detectors now parses every documented parameter with no bogus or missing entries.

Removed a dead pyod.models.auto_encoder_torch section (the module was deleted in 2024; a duplicated :exclude-members: made the directive raise DuplicateOptionError, which Sphinx stripped from the output, so the page silently rendered a heading with no body) and de-duplicated the pyod.models.base automodule.

Entry points

  • The README quick start called clf.fit(X_train) without ever defining X_train, and used visualize without importing it. Pasting it raised NameError. This block is the GitHub landing page and the PyPI description.
  • docs/install.rst documented a pytorch extra that does not exist. pip treats an unknown extra as a warning, so pip install pyod[pytorch] succeeded while installing none of the PyTorch stack, and the mistake surfaced later as an ImportError. The table now keys on the extras actually defined in pyproject.toml, adds the nine that were missing plus pip install pyod[all], corrects the MCP tool count from seven to ten, and drops the claim that pyod install skill supports Claude Desktop, which no code path targets.

Examples

mad_example.py generated two features for a univariate-only detector, and qmcd_example.py appended ground-truth labels to the feature matrix before calling predict — which raised, and would have leaked test labels if it had not. Both run now. examples/data/mat_file_conversion.py byte-compiles after removal of mid-file Python 2 __future__ imports; end-to-end conversion still needs its optional dependencies and external source datasets.

Deferred to issues

Three findings need a runtime decision and are tracked separately: #713 (CBLOF.n_jobs accepted but unused — now disclosed in its docstring), #714 (DevNet has no class docstring and five parameters, including random_state, are never read, so runs are not reproducible), and #715 (pyod info infers "Claude Code detected" from a directory pyod install skill creates itself).

Full suite: 1532 passed. Reviewed via /implement-review with Codex.