Skip to content

Commit 8f39dc6

Browse files
Fix BOCD API example
1 parent 1d52754 commit 8f39dc6

File tree

1 file changed

+26
-19
lines changed
  • frouros/detectors/concept_drift/streaming/change_detection

1 file changed

+26
-19
lines changed

frouros/detectors/concept_drift/streaming/change_detection/bocd.py

Lines changed: 26 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -2,12 +2,13 @@
22

33
import abc
44
import copy
5-
from typing import Union, Optional
5+
from typing import List, Union, Optional
66

77
import numpy as np # type: ignore
88
from scipy.special import logsumexp # type: ignore
99
from scipy.stats import norm # type: ignore
1010

11+
from frouros.callbacks.streaming.base import BaseCallbackStreaming
1112
from frouros.detectors.concept_drift.streaming.change_detection.base import (
1213
BaseChangeDetection,
1314
BaseChangeDetectionConfig,
@@ -122,8 +123,8 @@ def var_params(self):
122123
class BOCDConfig(BaseChangeDetectionConfig):
123124
"""BOCD (Bayesian Online Change Detection) [adams2007bayesian]_ configuration.
124125
125-
:param model: BOCD model, (e.g. :class:`frouros.detectors.concept_drift.streaming.change_detection.bocd.GaussianUnknownMean`)
126-
:type model: BaseBOCDModel
126+
:param model: BOCD model, defaults to None. If None, :class:`frouros.detectors.concept_drift.streaming.change_detection.bocd.GaussianUnknownMean` is used.
127+
:type model: Optional[BaseBOCDModel]
127128
:param hazard: hazard value, defaults to 0.01
128129
:type hazard: float
129130
:param min_num_instances: minimum numbers of instances to start looking for changes, defaults to 30
@@ -136,9 +137,11 @@ class BOCDConfig(BaseChangeDetectionConfig):
136137
arXiv preprint arXiv:0710.3742 (2007).
137138
""" # noqa: E501
138139

140+
model_type = GaussianUnknownMean
141+
139142
def __init__( # noqa: D107
140143
self,
141-
model: BaseBOCDModel = GaussianUnknownMean, # type: ignore
144+
model: Optional[BaseBOCDModel] = None, # type: ignore
142145
hazard: float = 0.01,
143146
min_num_instances: int = 30,
144147
) -> None:
@@ -166,20 +169,23 @@ def model(self, model: BaseBOCDModel) -> None:
166169
:type model: BaseBOCDModel
167170
:raises TypeError: if model is not an instance of BaseModel
168171
"""
169-
if not isinstance(model, BaseBOCDModel):
170-
raise TypeError(
171-
f"model must be an instance of BaseModel, not {type(model)}"
172-
)
173-
self._model = model
172+
if model is not None:
173+
if not isinstance(model, BaseBOCDModel):
174+
raise TypeError(
175+
f"model must be an instance of BaseModel, not {type(model)}"
176+
)
177+
self._model = model
178+
else:
179+
self._model = self.model_type()
174180

175181

176182
class BOCD(BaseChangeDetection):
177183
"""BOCD (Bayesian Online Change Detection) [adams2007bayesian]_ detector.
178184
179-
:param config: configuration object of the detector
180-
:type config: BOCDConfig
181-
:param callbacks: list of callbacks, defaults to None
182-
:type callbacks: list, optional
185+
:param config: configuration object of the detector, defaults to None. If None, the default configuration of :class:`BOCDConfig` is used.
186+
:type config: Optional[BOCDConfig]
187+
:param callbacks: callbacks, defaults to None
188+
:type callbacks: Optional[Union[BaseCallbackStreaming, List[BaseCallbackStreaming]]]
183189
184190
:Note:
185191
Adapted from the implementation in https://github.com/gwgundersen/bocd.
@@ -192,14 +198,13 @@ class BOCD(BaseChangeDetection):
192198
193199
:Example:
194200
195-
>>> from frouros.detectors.concept_drift import BOCD, BOCDConfig
196-
>>> from frouros.detectors.concept_drift.streaming.change_detection.bocd import GaussianUnknownMean
201+
>>> from frouros.detectors.concept_drift import BOCD
197202
>>> import numpy as np
198203
>>> np.random.seed(seed=31)
199204
>>> dist_a = np.random.normal(loc=0.2, scale=0.01, size=1000)
200205
>>> dist_b = np.random.normal(loc=0.8, scale=0.04, size=1000)
201206
>>> stream = np.concatenate((dist_a, dist_b))
202-
>>> detector = BOCD(config=BOCDConfig(model=GaussianUnknownMean()))
207+
>>> detector = BOCD()
203208
>>> for i, value in enumerate(stream):
204209
... _ = detector.update(value=value)
205210
... if detector.drift:
@@ -211,9 +216,11 @@ class BOCD(BaseChangeDetection):
211216
config_type = BOCDConfig # type: ignore
212217

213218
def __init__( # noqa: D107
214-
self,
215-
config: BOCDConfig,
216-
callbacks: list = None,
219+
self,
220+
config: Optional[BOCDConfig] = None,
221+
callbacks: Optional[
222+
Union[BaseCallbackStreaming, List[BaseCallbackStreaming]]
223+
] = None,
217224
) -> None:
218225
super().__init__(
219226
config=config,

0 commit comments

Comments
 (0)