CalibrationSession for full calibration loops, plus helpers for pool ranking, streaming label requests, and label-free stopping.
Active learning answers which trials to label. That is different from
Personalizer.recommend_adapt (whether to spend labels on stream partial_fit) and from BrainState trial rejection. See Personalizer overview for the adapt helper.Active learning operates on preprocessed feature rows (or already-encoded embeddings), not raw EEG. Use arrays shaped
(n_trials, n_features) for pools and (n_features,) or (1, n_features) for single streaming trials. With Personalizer, run AL on the head (adapter.head) or feed encoded pools into partial_fit.With Personalizer
Compose active learning with the product surface: choose labels, then update the Personalizer head.Core Workflow
Start with a small seed calibration set, rank an unlabeled feature pool, collect labels for the most informative trials, update withpartial_fit(), and stop when the posterior stops changing. For most applications, use CalibrationSession so pool bookkeeping and model snapshots stay consistent.
CalibrationSession
UseCalibrationSession when you want the SDK to manage the active pool, selected index history, partial_fit() updates, and the previous model snapshot needed by posterior_stability.
suggest_next_trial() returns indices local to the current active pool. Use session.remaining_indices[ranked.indices] when labels are stored against the original pool. update() captures the pre-update model snapshot, calls partial_fit(), removes selected rows, and increments round_index and n_labeled.
For
posterior_stability, call session.calibration_sufficient() only after at least one session.update(...). Before then, there is no previous model snapshot to compare.Session State
Useful properties and history fields:remaining_indices: original pool indices still available for querying.remaining_pool: feature rows still available for querying.n_remaining: number of candidates left.is_exhausted: whether no candidates remain.n_labeled: number of labels applied throughupdate().query_history:QueryResultobjects returned by session ranking calls.stopping_history:CalibrationStatusobjects returned by stopping checks.selected_global_indices: original pool indices selected each round.
When to Use Stateless Helpers
Use the lower-level helpers directly when you are building a custom loop, working with rawNimbusModel snapshots, or do not want the SDK to mutate a fitted classifier. CalibrationSession.update(...) requires a fitted Nimbus classifier with partial_fit().
Pool-Based Trial Ranking
Usesuggest_next_trial() when you have an unlabeled pool of candidate feature rows and want the top n trials to label next.
suggest_next_trial() accepts either a fitted Nimbus classifier (NimbusLDA, NimbusQDA, NimbusSoftmax, NimbusSTS) or a raw NimbusModel snapshot. It returns a QueryResult dataclass with:
indices: top-nindices intoX_pool.scores: raw informativeness score for every row inX_pool.strategy: the strategy used.n_posterior_samples: posterior samples used for the score (1for cheap strategies).
strategy="bald" is supported for NimbusLDA, NimbusQDA, and NimbusSoftmax. It is not supported for NimbusSTS in this release because STS posterior sampling needs temporal-coupling support.Streaming Query Gate
Useshould_query() when a single trial arrives during a live session and you need to decide whether asking for a label is worth the calibration cost.
StreamingQueryDecision dataclass with:
should_query: whether the score crossed the threshold.score: raw informativeness score.threshold: threshold used for the decision.strategy: strategy used.
Stopping Calibration
Usecalibration_sufficient() to stop collecting labels once additional cues are unlikely to change predictions over the pool.
calibration_sufficient() returns a CalibrationStatus dataclass with:
is_sufficient:Truewhen the criterion signal is below the threshold.signal: mean total variation forposterior_stability, or mean BALD forexpected_info_gain.threshold: threshold used for the comparison.criterion: criterion used.details: extra diagnostic values such as max/min TV or BALD.
Stopping Criteria
posterior_stability compares two consecutive model snapshots over the same X_pool. It measures the mean total-variation distance between predict_proba outputs and works for every Nimbus head, including NimbusSTS.
expected_info_gain measures mean BALD over the current pool. It does not use previous, and it is available for NimbusLDA, NimbusQDA, and NimbusSoftmax.
Strategy Guide
Practical Defaults
- Use
CalibrationSessionfor end-to-end calibration loops. - Start with
strategy="bald"for pool-based calibration when usingNimbusLDA,NimbusQDA, orNimbusSoftmax. - Use
num_posterior_samples=256for BALD ranking stability. Lower values can be faster but noisier. - Use
strategy="entropy"for streamingshould_query()gates. - Use
criterion="posterior_stability"for label-free stopping, with a threshold near0.02as an initial tuning point. - Keep
X_poolfixed across a calibration round so scores and stability checks are comparable.
Next Read
Python API Reference
Function signatures and dataclass fields for active learning.
Streaming Inference
Combine real-time prediction with query gates and feedback.
sklearn Integration
Use Nimbus classifiers inside sklearn workflows.
Model Selection
Choose the right Bayesian head before calibration.