# `SLEADE`

### *class* capymoa.ssl.SLEADE[[source]](https://github.com/adaptive-machine-learning/CapyMOA/blob/3e255b1/src/capymoa/ssl/_sleade.py#L16)

Bases: [`MOAClassifierSSL`](capymoa.base.MOAClassifierSSL.md#capymoa.base.MOAClassifierSSL)

Semi-supervised SLEADE ensemble.

SLEADE handles partially labelled data by having ensemble members teach one
another: a member is trained on a pseudo-label when the rest of the ensemble
predicts it with more confidence than that member would itself. Unsupervised
drift detection lets the ensemble react to change without waiting for labels.

The defaults are the configuration used in the paper, so `SLEADE(schema)`
reproduces the published method. In particular pseudo-labels are only accepted
above `ssl_min_confidence`, and the base ensemble runs with its own drift
detection and background learner disabled, because SLEADE supplies its own
unsupervised drift detection instead.

Reference:

Gomes, H. M., Read, J., Grzenda, M., Pfahringer, B., & Bifet, A. (2025).
*SLEADE: Disagreement-Based Semi-Supervised Learning for Sparsely Labeled
Evolving Data Streams.* IEEE Transactions on Knowledge and Data Engineering.

```pycon
>>> from capymoa.ssl import SLEADE
>>> from capymoa.datasets import ElectricityTiny
>>> from capymoa.evaluation import prequential_evaluation
>>>
>>> stream = ElectricityTiny()
>>> clf = SLEADE(stream.get_schema())
>>> results = prequential_evaluation(stream, clf, max_instances=1000)
>>> print(f"{results['cumulative'].accuracy():.1f}")
90.2
```

#### \_\_init_\_(schema: [Schema](capymoa.stream.Schema.md#capymoa.stream.Schema), random_seed: [int](https://docs.python.org/3/builtins/functions.html#int) = 0, ensemble_size: [int](https://docs.python.org/3/builtins/functions.html#int) = 10, confidence_strategy: [Literal](https://docs.python.org/3/library/typing.html#typing.Literal)['Sum', 'ArgMax'] = 'ArgMax', enable_random_threshold: [bool](https://docs.python.org/3/builtins/functions.html#bool) = False, auto_weight_shrinkage: [Literal](https://docs.python.org/3/library/typing.html#typing.Literal)['Constant', 'LabeledDivTotal', 'LabeledNoWarmupDivTotal'] = 'LabeledNoWarmupDivTotal', ssl_strategy: [Literal](https://docs.python.org/3/library/typing.html#typing.Literal)['PseudoLabelAll', 'PseudoLabelCheckConfidence'] = 'PseudoLabelCheckConfidence', ssl_min_confidence: [float](https://docs.python.org/3/builtins/functions.html#float) = 0.9, weight_function: [Literal](https://docs.python.org/3/library/typing.html#typing.Literal)['Constant1', 'Confidence', 'ConfidenceWeightShrinkage', 'UnsupervisedDetectionWeightShrinkage'] = 'ConfidenceWeightShrinkage', pairing_function: [Literal](https://docs.python.org/3/library/typing.html#typing.Literal)['MinKappa', 'Random', 'MajorityTrainsMinority'] = 'MajorityTrainsMinority', ssl_weight_shrinkage: [float](https://docs.python.org/3/builtins/functions.html#float) = 100.0, use_unsupervised_drift_detection: [bool](https://docs.python.org/3/builtins/functions.html#bool) = True, student_learner: [Classifier](capymoa.base.Classifier.md#capymoa.base.Classifier) | [None](https://docs.python.org/3/builtins/constants.html#None) = None, drift_detection_method: [MOADriftDetector](capymoa.drift.base_detector.MOADriftDetector.md#capymoa.drift.base_detector.MOADriftDetector) | [None](https://docs.python.org/3/builtins/constants.html#None) = None, unsupervised_detection_weight_window: [int](https://docs.python.org/3/builtins/functions.html#int) = 20, labeled_window_limit: [int](https://docs.python.org/3/builtins/functions.html#int) = 100)[[source]](https://github.com/adaptive-machine-learning/CapyMOA/blob/3e255b1/src/capymoa/ssl/_sleade.py#L47)

Construct the SLEADE semi-supervised ensemble.

* **Parameters:**
  * **schema** – Stream schema.
  * **random_seed** – Random seed.
  * **ensemble_size** – Number of learners in the base ensemble. SLEADE is
    built on [`StreamingRandomPatches`](capymoa.classifier.StreamingRandomPatches.md#capymoa.classifier.StreamingRandomPatches), which is
    configured internally with its own drift detection and background
    learner disabled so that SLEADE’s unsupervised drift detection is what
    responds to change.
  * **confidence_strategy** – How a prediction’s confidence is derived from
    the votes: `"Sum"` uses the votes directly, `"ArgMax"` assigns 1 to
    the argmax of each vote array.
  * **enable_random_threshold** – Draw the minimum confidence at random
    instead of using a fixed threshold. When set, `ssl_min_confidence`
    is **ignored**.
  * **auto_weight_shrinkage** – Strategy for setting the weight shrinkage
    automatically.
  * **ssl_strategy** – Whether to pseudo-label everything, or only instances
    passing the confidence check.
  * **ssl_min_confidence** – Minimum confidence for a pseudo-label to be used
    for training. Ignored when `enable_random_threshold` is set.
  * **weight_function** – How pseudo-labelled instances are weighted.
    `"UnsupervisedDetectionWeightShrinkage"` only makes sense together
    with `use_unsupervised_drift_detection`.
  * **pairing_function** – How learners are paired for teaching.
  * **ssl_weight_shrinkage** – Pseudo-labelled instances are weighted by
    `instance weight * 1/ws`.
  * **use_unsupervised_drift_detection** – Whether to use the unsupervised
    drift detection and recovery strategy.
  * **student_learner** – Model trained to mimic the ensemble’s predictions.
    Because it learns from those predictions rather than from labels, its
    error can be tracked without any labelled data, and a change in that
    error is what signals drift. Only used when
    `use_unsupervised_drift_detection` is set. Defaults to
    `HoeffdingTree(grace_period=50, confidence=0.01)`.
  * **drift_detection_method** – Change detector applied to the student’s
    error. Defaults to `ADWIN(delta=1e-5)`.
  * **unsupervised_detection_weight_window** – Length of the sigmoid used to
    weight pseudo-labelled instances after an unsupervised detection.
  * **labeled_window_limit** – Maximum number of labelled instances kept in
    the sliding window used to quick-start learners.

#### cli_help()[[source]](https://github.com/adaptive-machine-learning/CapyMOA/blob/3e255b1/src/capymoa/base/_classifier.py#L111)

#### *classmethod* from_params(schema: [Any](https://docs.python.org/3/library/typing.html#typing.Any) = None, params: [dict](https://docs.python.org/3/builtins/stdtypes.html#dict)[[str](https://docs.python.org/3/builtins/stdtypes.html#str), [Any](https://docs.python.org/3/library/typing.html#typing.Any)] | [None](https://docs.python.org/3/builtins/constants.html#None) = None, random_seed: [int](https://docs.python.org/3/builtins/functions.html#int) = 1) → [Any](https://docs.python.org/3/library/typing.html#typing.Any)[[source]](https://github.com/adaptive-machine-learning/CapyMOA/blob/3e255b1/src/capymoa/base/_learner_params.py#L170)

Construct an instance from parameters produced by `get_params`.

#### get_params() → [dict](https://docs.python.org/3/builtins/stdtypes.html#dict)[[str](https://docs.python.org/3/builtins/stdtypes.html#str), [Any](https://docs.python.org/3/library/typing.html#typing.Any)][[source]](https://github.com/adaptive-machine-learning/CapyMOA/blob/3e255b1/src/capymoa/base/_learner_params.py#L163)

Return the hyper-parameters captured from the constructor.

#### predict(instance: [Instance](capymoa.core.Instance.md#capymoa.core.Instance)) → [int](https://docs.python.org/3/builtins/functions.html#int) | [None](https://docs.python.org/3/builtins/constants.html#None)[[source]](https://github.com/adaptive-machine-learning/CapyMOA/blob/3e255b1/src/capymoa/base/_classifier.py#L56)

Predict the label of an instance.

The base implementation calls [`predict_proba()`](#capymoa.ssl.SLEADE.predict_proba) and returns the
label with the highest probability.

* **Parameters:**
  **instance** – The instance to predict the label for.
* **Returns:**
  The predicted label or `None` if the classifier is unable
  to make a prediction.

#### predict_proba(instance) → [ndarray](https://numpy.org/doc/stable/reference/generated/numpy.ndarray.html#numpy.ndarray)[[tuple](https://docs.python.org/3/builtins/stdtypes.html#tuple)[[Any](https://docs.python.org/3/library/typing.html#typing.Any), ...], [dtype](https://numpy.org/doc/stable/reference/generated/numpy.dtype.html#numpy.dtype)[float64]] | [None](https://docs.python.org/3/builtins/constants.html#None)[[source]](https://github.com/adaptive-machine-learning/CapyMOA/blob/3e255b1/src/capymoa/base/_classifier.py#L117)

Return probability estimates for each label.

* **Parameters:**
  **instance** – The instance to estimate the probabilities for.
* **Returns:**
  An array of probabilities for each label or `None` if the
  classifier is unable to make a prediction.

#### train(instance)[[source]](https://github.com/adaptive-machine-learning/CapyMOA/blob/3e255b1/src/capymoa/base/_classifier.py#L114)

Train the classifier with a labeled instance.

* **Parameters:**
  **instance** – The labeled instance to train the classifier with.

#### train_on_unlabeled(instance: [Instance](capymoa.core.Instance.md#capymoa.core.Instance))[[source]](https://github.com/adaptive-machine-learning/CapyMOA/blob/3e255b1/src/capymoa/base/_ssl.py#L18)

#### random_seed *: [int](https://docs.python.org/3/builtins/functions.html#int)*

The random seed for reproducibility.

When implementing a classifier ensure random number generators are seeded.

#### schema *: [Schema](capymoa.stream.Schema.md#capymoa.stream.Schema)*

The schema representing the instances.
