Skip to content

Commit 4ef6ee5

Browse files
authored
Merge pull request #24 from selimfirat/develop
Release v0.3.3
2 parents e825849 + 5caa756 commit 4ef6ee5

File tree

8 files changed

+66
-37
lines changed

8 files changed

+66
-37
lines changed

.travis.yml

Lines changed: 0 additions & 30 deletions
This file was deleted.

CHANGES.txt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,4 +2,5 @@ v<0.1.0>, <08/15/2020> -- Initial release.
22
v<0.2.0> <06/10/2023> -- Upgraded some libraries like numpy,pandas and small refactorings.
33
v<0.3.0>, <05/23/2025> -- Updated dependencies to latest versions, improved documentation, added quick start example in README. Added Inqmad model. Special thanks to @TechyNilesh @Joaggi @onixlas.
44
v<0.3.1>, <06/04/2025> -- Enhanced README with comprehensive community engagement section, educational content, third-party integrations, and developer community highlights. Fixed sublist formatting in reStructuredText. Improved error handling for Inqmad model imports.
5-
v<0.3.2>, <06/14/2025> -- Updated PyOD version and added Python 3.13 support. Fixed Flaticon link in documentation. Enhanced error handling for optional JAX dependencies. Updated rrcf version to 0.4.4 and improved quantization in RelativeEntropy model. Improved test coverage and configuration. Added deprecation warning tests and enhanced model methods array handling. Special thanks to @onixlas for multiple contributions.
5+
v<0.3.2>, <06/14/2025> -- Updated PyOD version and added Python 3.13 support. Fixed Flaticon link in documentation. Enhanced error handling for optional JAX dependencies. Updated rrcf version to 0.4.4 and improved quantization in RelativeEntropy model. Improved test coverage and configuration. Added deprecation warning tests and enhanced model methods array handling. Special thanks to @onixlas for multiple contributions.
6+
v<0.3.3>, <06/19/2025> -- Fixed critical bugs in ReferenceWindowModel: resolved data mutation issues by ensuring reference window data is properly copied, fixed window_length parameter naming to window_size, and improved reference window label management. Enhanced test coverage and fixed minor typo in bibtex reference. Special thanks to @onixlas for bug reports and fixes.

azure-pipelines.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,12 @@ steps:
2929
versionSpec: '$(python.version)'
3030
displayName: 'Use Python $(python.version)'
3131

32+
- script: |
33+
# Install system dependencies required for building scipy from source
34+
sudo apt-get update
35+
sudo apt-get install -y libopenblas-dev liblapack-dev gfortran pkg-config
36+
displayName: 'Install system dependencies'
37+
3238
- script: |
3339
python -m pip install --upgrade pip
3440
pip install -r requirements-ci.txt

docs/refs.bib

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -131,7 +131,7 @@ @article{constantinou2018pynomaly
131131

132132
@article{pevny2016loda,
133133
title={Loda: Lightweight on-line detector of anomalies},
134-
author={Pevn{\`y}, Tom{\'a}{\v{s}}},
134+
author={Pevn{\'y}, Tom{\'a}{\v{s}}},
135135
journal={Machine Learning},
136136
volume={102},
137137
number={2},

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
44

55
[project]
66
name = "pysad"
7-
version = "0.3.2"
7+
version = "0.3.3"
88
dependencies = [
99
"numpy",
1010
"scikit-learn",

pysad/models/integrations/reference_window_model.py

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33

44

55
class ReferenceWindowModel(PYODModel):
6-
"""This PyOD model wrapper wraps the batch anomaly detectors. This wrapper keeps track of the reference window of size `window_length`. For every `sliding_size` instnaces, it resets the model by training new `model_cls` instance with the reference window. This implementation is based on the reference windowing described in :cite:`xstream`.
6+
"""This PyOD model wrapper wraps the batch anomaly detectors. This wrapper keeps track of the reference window of size `window_size`. For every `sliding_size` instances, it resets the model by training new `model_cls` instance with the reference window. This implementation is based on the reference windowing described in :cite:`xstream`.
77
88
Args:
99
model_cls (class): The model class to be instantiated.
@@ -65,8 +65,8 @@ def fit_partial(self, X, y=None):
6565

6666
if not self.initial_ref_window and len(
6767
self.cur_window_X) < self.window_size:
68-
self.reference_window_X = self.cur_window_X
69-
self.reference_window_y = self.cur_window_y if y is not None else None
68+
self.reference_window_X = self.cur_window_X.copy()
69+
self.reference_window_y = self.cur_window_y.copy() if y is not None else None
7070
self._fit_model()
7171
elif len(self.cur_window_X) % self.sliding_size == 0:
7272
self.reference_window_X = np.concatenate(

pysad/version.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -21,4 +21,4 @@
2121
# 'X.Y.dev0' is the canonical version of 'X.Y.dev'
2222
#
2323

24-
__version__ = '0.3.2'
24+
__version__ = '0.3.3'

tests/models/test_pyod_integrations.py

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,3 +219,55 @@ def test_reference_window_model_window_update():
219219

220220
# Check internal state
221221
assert len(model.cur_window_X) <= model.window_size
222+
223+
224+
def test_reference_window_model_issue_23_fix():
225+
"""Test for the fix of issue #23: reference window duplication bug.
226+
227+
The bug was that reference_window_X and cur_window_X pointed to the same
228+
list object, causing data duplication when concatenation occurred.
229+
"""
230+
from pysad.models.integrations.reference_window_model import ReferenceWindowModel
231+
from pyod.models.iforest import IForest
232+
import numpy as np
233+
234+
# Setup from issue #23
235+
window_size = 4
236+
sliding_size = 2
237+
238+
model = ReferenceWindowModel(
239+
model_cls=IForest,
240+
window_size=window_size,
241+
sliding_size=sliding_size,
242+
initial_window_X=None
243+
)
244+
245+
# Step 1: Add first data point
246+
X1 = np.array([1.0])
247+
model.fit_partial(X1)
248+
249+
# Verify that cur_window_X and reference_window_X are independent objects
250+
assert model.cur_window_X is not model.reference_window_X, \
251+
"cur_window_X and reference_window_X should be independent objects"
252+
253+
# Step 2: Add second data point
254+
X2 = np.array([2.0])
255+
model.fit_partial(X2)
256+
257+
# Verify they are still independent
258+
assert model.cur_window_X is not model.reference_window_X, \
259+
"cur_window_X and reference_window_X should remain independent objects"
260+
261+
# Test independence: modify cur_window_X and ensure reference_window_X is unchanged
262+
original_ref_len = len(model.reference_window_X)
263+
model.cur_window_X.append(np.array([999.0]))
264+
265+
# reference_window_X should not be affected by changes to cur_window_X
266+
assert len(model.reference_window_X) == original_ref_len, \
267+
"reference_window_X should not be affected by changes to cur_window_X"
268+
269+
# Extract values for comparison - should be [1.0, 2.0], NOT [1.0, 2.0, 1.0, 2.0]
270+
ref_values = [x[0] for x in model.reference_window_X]
271+
expected = [1.0, 2.0]
272+
assert ref_values == expected, \
273+
f"Expected {expected}, but got {ref_values}. Duplication detected!"

0 commit comments

Comments
 (0)