PeriodicTrigger¶
Generate pseudo drift detection signals.
There are two approaches1:
fixed
where the drift signal is generated everyt_0
samples. -random
corresponds to a pseudo-random drift detection strategy.
Parameters¶
-
trigger_method (str) – defaults to
fixed
The trigger method to use.
*fixed
*random
-
t_0 (int) – defaults to
300
Reference point to define triggers.
-
w (int) – defaults to
0
Auxiliary parameter whose purpose is twofold: - if
trigger_method="fixed"
, the periodic drift signals will only start after an initial warm-up period randomly defined between[0, w]
. Useful to avoid that all ensemble members are reset at the same time when periodic triggers are used as the adaptation strategy. - iftrigger_method="random"
,w
defines the probability bounds of triggering a drift. The chance of triggering a drift is \(0.5\) after observingt_0
instances and becomes \(1\) after monitoringt_0 + w / 2
instances. A sigmoid function is used to produce values between[0, 1]
that are used as the reset probabilities. -
dynamic_cloning (bool) – defaults to
False
Whether to change the
seed
andw
values each timeclone()
is called. -
seed (int) – defaults to
None
Random seed for reproducibility.
Attributes¶
-
change_detected
Concept drift alarm. True if concept drift is detected.
-
warning_detected
Warning zone alarm. Indicates if the drift detector is in the warning zone. Applicability depends on each drift detector implementation. True if the change detector is in the warning zone.
Examples¶
>>> import random
>>> from river import drift
>>> rng = random.Random(42)
The observed values will not affect the periodic triggers.
>>> data = [rng.gauss(0, 1) for _ in range(1000)]
Let's start with the fixed drift signals:
>>> ptrigger = PeriodicTrigger(t_0=500, seed=42)
>>> for i, v in enumerate(data):
... in_drift, _ = ptrigger.update(v)
... if in_drift:
... print(f"Drift detected at instance {i}.")
Drift detected at instance 499.
Drift detected at instance 999.
Now, the random drift signals:
>>> rtrigger = PeriodicTrigger(
... trigger_method="random",
... t_0=500,
... w=100,
... dynamic_cloning=True,
... seed=42
... )
>>> for i, v in enumerate(data):
... in_drift, _ = rtrigger.update(v)
... if in_drift:
... print(f"Drift detected at instance {i}.")
Drift detected at instance 368.
Drift detected at instance 817.
Remember to set a w > 0 value if random triggers are used:
>>> try:
... PeriodicTrigger(trigger_method="random")
... except ValueError as ve:
... print(ve)
The 'w' value must be greater than zero when 'trigger_method' is 'random'.
Since we set dynamic_cloning
to True
, a clone of the periodic trigger will
have its internal paramenters changed:
>>> rtrigger = rtrigger.clone()
>>> for i, v in enumerate(data):
... in_drift, _ = rtrigger.update(v)
... if in_drift:
... print(f"Drift detected at instance {i}.")
Drift detected at instance 429.
Drift detected at instance 728.
Methods¶
clone
Return a fresh estimator with the same parameters.
The clone has the same parameters but has not been updated with any data. This works by looking at the parameters from the class signature. Each parameter is either - recursively cloned if it's a River classes. - deep-copied via copy.deepcopy
if not. If the calling object is stochastic (i.e. it accepts a seed parameter) and has not been seeded, then the clone will not be idempotent. Indeed, this method's purpose if simply to return a new instance with the same input parameters.
reset
Reset the change detector.
update
Update the change detector with a single data point.
Parameters
- value (numbers.Number)
Returns
typing.Tuple[bool, bool]: A tuple (drift, warning) where its elements indicate if a drift or a warning is detected.
Notes¶
When used in ensembles, a naive implementation of periodic drift signals would make all ensemble members
reset at the same time. To avoid that, the dynamic_cloning
parameter can be set to True
. In this case,
every time the clone
method of this detector is called in an ensemble a new seed
is defined. If
dynamic_cloning=True
and trigger_method="fixed"
, a new w
between [0, t_0]
will also be created
for the new cloned instance.
References¶
-
Heitor Gomes, Jacob Montiel, Saulo Martiello Mastelini, Bernhard Pfahringer, and Albert Bifet. On Ensemble Techniques for Data Stream Regression. IJCNN'20. International Joint Conference on Neural Networks. 2020. ↩