Skip to content

Add tested NSA-inspired novelty detection with eleven generation strategies - #747

Open
kishordgupta wants to merge 4 commits into
yzhao062:developmentfrom
kishordgupta:add-negative-selection-reviewed
Open

kishordgupta wants to merge 4 commits into
yzhao062:developmentfrom
kishordgupta:add-negative-selection-reviewed

Conversation

@kishordgupta

@kishordgupta kishordgupta commented Sep 16, 2026 •

Copy link
Copy Markdown

This adds one NSA novelty detector for training on known normal/self samples, with eleven distinct generation strategies and thirteen configurations including the three binary matching rules. Each strategy has a substantive implementation and explicit NSA-inspired labeling.

The strategies are binary, fixed, variable, coverage, grid, hierarchical, voronoi, deterministic, suppressed, dual and annealed. Primary citations and the precise differences from the papers are documented. Statistical coverage stopping uses frozen-population exact-binomial tests with alpha spending; budget exhaustion is never claimed as coverage success. Hierarchical allocation reserves capacity for finer levels even when only one detector or candidate draw is available. Geometry limits, bounded clustering and annealing schedules are explicit. No unsupported method acronyms or published-performance claims are exposed.

The estimator follows BaseDetector scoring and threshold conventions, is exported through the package and ADEngine registry, and has runnable real-data examples with an IForest baseline. All supplied rows remain self; contamination calibrates the score threshold. Any fit failure clears every learned marker, including those recognized by generic sklearn check_is_fitted, so a failed refit cannot leave a stale fitted state.

Local validation on the source synchronized with PyOD 3.6.6: 428 NSA tests and 13 subtests passed; 359 integration and upstream-regression tests passed, with 1 skipped; 98% combined statement/branch coverage across NSA and its helpers. Strict flake8, generated-reference consistency, wheel/sdist build and package metadata checks pass. Sphinx builds successfully with existing documentation diagnostics in unrelated modules and no NSA-specific diagnostics. The PCA2 real-data example preserves the same train/test split for all compared methods and reports IForest's stronger result; no ranking or automatic routing rule is added.

I commit to maintaining this contributed detector for at least two years, including compatibility fixes, tests and documentation.

@chatgpt-codex-connector

chatgpt-codex-connector Bot commented Sep 16, 2026 •

Copy link
Copy Markdown

Codex Review Summary

This comment shows the latest Codex review activity on this pull request.

Review Status Commit Review trigger
📝 Code Review ✅ Completed 2026-10-14T11:41:26.939564Z 277326a New commits
ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review" or "@codex security review".

Codex reacts with 👀 while any review is running, comments if it has suggestions, and reacts with 👍 once all reviews finish with no findings.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 587fa62856

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pyod/models/nsa.py Outdated
@coveralls

coveralls commented Sep 16, 2026 •

Copy link
Copy Markdown

Coverage Report for CI Build 35058654472

Warning

Build has drifted: This PR's base is out of sync with its target branch, so coverage data may include unrelated changes.
Quick fix: rebase this PR. Learn more →

Coverage increased (+0.7%) to 93.25%

Details

  • Coverage increased (+0.7%) from the base build.
  • Patch coverage: 15 uncovered changes across 7 files (2233 of 2248 lines covered, 99.33%).
  • 4 coverage regressions across 4 files.

Uncovered Changes

File Changed Covered %
pyod/models/nsa.py 239 235 98.33%
pyod/models/_nsa_cluster.py 154 151 98.05%
pyod/models/init.py 6 4 66.67%
pyod/models/_nsa_grid.py 190 188 98.95%
pyod/test/test_nsa_optimization.py 405 403 99.51%
pyod/models/_nsa_optimization.py 245 244 99.59%
pyod/test/test_nsa_grid.py 173 172 99.42%
Total (13 files) 2248 2233 99.33%

Coverage Regressions

4 previously-covered lines in 4 files lost coverage.

File Lines Losing Coverage Coverage
pyod/models/copod.py 1 90.0%
pyod/models/ecod.py 1 90.28%
pyod/test/test_deepsvdd.py 1 99.39%
pyod/utils/utility.py 1 97.39%

Coverage Stats

Coverage Status
Relevant Lines: 22962
Covered Lines: 21412
Line Coverage: 93.25%
Coverage Strength: 0.93 hits per line

💛 - Coveralls

@kishordgupta kishordgupta changed the title Add tested NSA-inspired novelty detection with three strategies Add tested NSA-inspired novelty detection with eleven generation strategies Sep 16, 2026

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: f7a9d73040

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

Comment thread pyod/models/_nsa_cluster.py Outdated
Carry detector and candidate quotas forward to finer hierarchy levels, add tiny-budget regressions, and synchronize with upstream development at 97fa2b4.

Copy link
Copy Markdown
Author

Updated the branch in 6a856c4 with the hierarchical-budget fix and a normal merge of current development at 97fa2b4. GitHub comparison now reports zero commits behind development.

For the Coveralls drift notice: build 81781369 compared the August base build at ad39845 against a synthetic PR merge containing newer upstream commits. The four listed regression files (COPOD, ECOD, DeepSVDD tests, and utility.py) were changed upstream and are not edited by this PR, so that report includes changes outside the contribution. The refreshed CI run is https://github.com/yzhao062/pyod/actions/runs/35111771147; its coverage result is still pending.

Local validation of the published source: 428 NSA tests plus 13 subtests passed; 359 integration/upstream-regression tests passed with one skip; NSA/helper statement-and-branch coverage remains 98%. PyOD 3.6.6 wheel/sdist builds, metadata checks, strict lint, generated-reference checks, and the real-data example passed. Sphinx builds successfully with existing unrelated documentation diagnostics.

@yzhao062 yzhao062 left a comment

Copy link
Copy Markdown
Owner

Choose a reason for hiding this comment

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

Thank you for the substantial rewrite. Before an inclusion decision, please state the operating regime where NSA is the right choice and show representative evidence for it. The demonstration in the description reports ROC AUC of 0.27 to 0.65 against 0.97 for IForest on one dataset.

Please also drop the lazy package-level NSA export, since PyOD imports detectors from their modules. The pull request has grown to about 4,500 lines across 26 files; a slimmer core would be easier to review and maintain.

Copy link
Copy Markdown
Author

Thank you for the feedback. I ran a broader benchmark to identify the regime where NSA may be useful. The clearest result is for Dual NSA under a normal-only cold start.

Normal-only cold start means training a detector from a small set of confirmed normal observations, with no real outlier examples used in preprocessing or initial fitting.
It reflects a newly installed sensor system that must detect unusual behavior before sufficient operating history or fault examples have been collected.

The benchmark covers 17 ODDS datasets and five seeds, with all 43 other PyOD tabular entries accounted for, including unsuccessful and inapplicable configurations. In the PCA(2) pipeline, Dual NSA's results are:

Retained normal training pool Mean AUROC / AP AUROC rank Top position in the fixed field PDF table / page
100% reference 0.7172 / 0.4718 13/26 50.00% 2 / 5
25% 0.7603 / 0.4699 10/26 38.46% 3 / 6
10% 0.7626 / 0.4206 6/26 23.08% 4 / 7
5% 0.7264 / 0.3755 5/26 19.23% 5 / 8

The 12-page paper provides the per-dataset comparisons and Total rows in Tables 2–5; Table 1 summarizes the settings. These are equally weighted dataset means. The comparison field stays fixed at 25 fully covered PyOD baselines plus Dual, and top position means 100 × rank / 26. At 5%, fitting uses only 4–30 normal rows. The ranking gain also persists in the separate neural batch-size sensitivity and the comparison restricted to pointwise scorers.

This gives evidence for a competitive initial option under scarce normal data. KDE remains ahead in mean AUROC at the two smallest sizes, Dual's AP declines, and results vary across datasets. The sensor cold-start use case still needs chronological validation. The code, raw results, and full paper with the appendix are available in the same repository.

Would this narrower operating regime and the broader evidence provide a convincing case for a smaller NSA contribution? If so, I can restructure the PR into a slimmer documented core, remove the lazy package-level export, and use the usual from pyod.models.nsa import NSA import.

@chatgpt-codex-connector chatgpt-codex-connector Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

💡 Codex Review

Here are some automated review suggestions for this pull request.

Reviewed commit: 277326a480

ℹ️ About Codex in GitHub

Your team has set up Codex to review pull requests in this repo. Reviews are triggered when you

  • Open a pull request for review
  • Mark a draft as ready
  • Comment "@codex review".

If Codex has suggestions, it will comment; otherwise it will react with 👍.

Codex can also answer questions or update the PR. Try commenting "@codex address that feedback".

np.r_[np.zeros(dimension), -1.0],
A_ub=np.column_stack((normals, np.ones(len(normals)))),
b_ub=-offsets, bounds=[(None, None)] * dimension + [(0, None)],
method='highs')

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P2 Badge Use a solver supported by the minimum SciPy version

In environments permitted by requirements.txt with SciPy 1.5.x, linprog does not yet support the highs method (it was added in SciPy 1.6), so every NSA(strategy='voronoi') fit fails with an unknown-solver error before constructing a cell. Use a solver available in SciPy 1.5 or raise the package's minimum SciPy requirement.

Useful? React with 👍 / 👎.

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.

3 participants