Bayesian STS - Bayesian Structural Time Series
Python:NimbusSTS | Julia: Not currently availableMathematical Model: State-Space Model with Extended Kalman Filter (EKF) Bayesian STS is a stateful Bayesian classification model designed for non-stationary BCI data. It combines feature-based classification with latent state dynamics, allowing it to adapt to temporal drift, electrode changes, and long-session fatigue.
Python head: prefer standalone
NimbusSTS / streaming sessions for latent-state adaptation. Personalizer currently ships lda / qda / softmax heads; STS remains the classical path for non-stationary sessions. See Personalizer & Middleware.Available in Python SDK:
- Python SDK:
NimbusSTSclass (sklearn-compatible with state management) - Julia SDK: Not currently available
Start Here
Quickstart
Start with SDK setup and first inference workflow.
Model Selection
Compare Nimbus models by data characteristics and use case.
Examples
See practical BCI examples for training and inference.
Overview
Bayesian STS extends beyond traditional static classifiers by modeling latent state evolution over time: ✅ Temporal state dynamics with Extended Kalman Filter✅ Drift adaptation for non-stationary data
✅ State management API for explicit time propagation
✅ Online learning with delayed feedback support
✅ Cross-session transfer with state persistence
✅ Uncertainty quantification for predictions and states
✅ Fast inference (~20-30ms per trial)
Quick Start
- Python
When to Use Bayesian STS
Bayesian STS is ideal for:- Non-stationary data with temporal drift
- Long BCI sessions (>30 minutes) with fatigue effects
- Cross-day experiments with electrode position changes
- Adaptive BCI systems with delayed feedback
- Online learning scenarios with continuous adaptation
- Environments with changing noise characteristics
- Data is stationary (class distributions don’t change over time)
- Sessions are short (<10 minutes)
- You need the absolute fastest inference (<15ms)
- Complexity of state management is not warranted
Model Architecture
Mathematical Foundation (State-Space Model)
Bayesian STS implements a state-space model with Extended Kalman Filter inference: Latent Dynamics:z_t= latent state at time t (captures temporal patterns like class prior drift)A= state transition matrix (default: identity for random walk)Q= process noise covariance (controls drift speed)W= feature weight matrixH= state-to-logit projection matrixx_t= observed features
z captures temporal patterns that persist across samples, such as gradual shifts in class priors due to fatigue or electrode drift.
Inference with Extended Kalman Filter
During training, the EKF updates the latent state using observed labels (measurement update). During inference:propagate_state(): Advance the prior without labels (time update only)partial_fit(): Update state with new label (measurement update)predict_proba(): Never mutates state (consistent with sklearn API)
Hyperparameters
Bayesian STS supports configurable hyperparameters for optimal performance: Available Hyperparameters:
Critical Parameter:
transition_cov (Q)
This controls how fast the latent state can drift:
-
0.001: Very slow drift (multi-day stability)
- Use for: Short sessions, stable recording conditions
- Example: 10-minute calibration sessions
-
0.01: Moderate drift (within-session adaptation)
- Use for: Standard BCI sessions (30-60 minutes)
- Example: Motor imagery with gradual fatigue
-
0.1: Fast drift (rapid environmental changes)
- Use for: Highly non-stationary environments
- Example: Mobile BCI, changing electrode impedance
None, auto-estimated from data.
Model Structure
The NimbusSTS classifier maintains:- Feature weights
W(learned during training) - State projection
H(learned during training) - Current state mean
z_mean(updated online) - Current state covariance
z_cov(updated online) - Initial state
z_mean_init,z_cov_init(for reset)
Usage
1. Basic Training and Prediction
- Python
predict() and predict_proba() never mutate the state (sklearn API compatibility). For time-ordered evaluation, use propagate_state() explicitly.
2. Stateful Prediction with Time Propagation
For time-ordered streaming data, explicitly propagate state between samples:- Python
3. Online Learning with Delayed Feedback
The canonical BCI paradigm: predict → user acts → receive feedback → update- Python
4. State Inspection and Transfer
Save and restore latent state across sessions:- Python
5. State Reset and Management
Reset state to initial values from training:- Python
6. Batch Inference
Standard sklearn-compatible batch inference:- Python
7. Streaming Inference with StreamingSessionSTS
Real-time chunk-by-chunk processing with state management:For detailed streaming examples, see Python SDK Streaming Inference.
- Python
StreamingSessionSTS automatically calls propagate_state() between chunks, properly handling temporal dynamics.
Hyperparameter Tuning
Fine-tune NimbusSTS for your specific drift characteristics.When to Tune Hyperparameters
Consider tuning when:- Default performance is unsatisfactory on non-stationary data
- You observe significant drift or fatigue effects
- You need to balance adaptation speed vs stability
- Cross-session performance is poor
Tuning transition_cov (Critical Parameter)
The process noise covariance controls drift speed:
For Stable, Short Sessions
- Session duration < 15 minutes
- Excellent electrode stability
- Controlled lab environment
- Minimal user fatigue
For Standard Sessions with Gradual Drift
- Session duration 30-60 minutes
- Standard BCI recording conditions
- Gradual fatigue or attention changes
- This is the recommended starting point
For Highly Non-Stationary Environments
- Mobile BCI or changing environments
- Electrode impedance changes during session
- Rapid user state changes
- Real-world deployment scenarios
Auto-Estimation
If unsure, let the model estimatetransition_cov from data:
Hyperparameter Search Example
Systematically search for optimal hyperparameters:Quick Tuning Guidelines
Training Requirements
Data Requirements
- Minimum: 40 trials per class
- Recommended: 80+ trials per class for stable initialization
- For fine-tuning: 10-20 trials with
partial_fit()
Feature Normalization
Feature Requirements
NimbusSTS expects preprocessed features, not raw EEG: ✅ Required preprocessing:- Bandpass filtering (paradigm-specific)
- Artifact removal (ICA recommended)
- Spatial filtering (CSP for motor imagery)
- Feature extraction (log-variance, bandpower, etc.)
- Temporal aggregation (for batch training)
- Raw EEG channels
- Unfiltered data
Performance Characteristics
Computational Performance
All measurements on standard CPU (no GPU required).
Classification Accuracy
Key Insight: NimbusSTS shines on non-stationary data where static models degrade over time. For short, stationary sessions, use NimbusLDA for faster inference.
Latency Trade-offs
Model Inspection
View Current State
Monitor State Evolution
View Model Parameters
Advantages & Limitations
Advantages
✅ Handles Non-Stationarity: Explicitly models temporal drift✅ Adaptive: Continuously learns from feedback
✅ Cross-Session Transfer: State persistence across days
✅ Uncertainty Quantification: For both predictions and states
✅ Delayed Feedback Support: Natural for BCI paradigms
✅ Production-Ready: Real-time capable with <30ms latency
✅ sklearn-Compatible: Works with pipelines and CV
Limitations
❌ More Complex API: State management requires careful usage❌ Slightly Slower: 5-10ms overhead vs static models
❌ Requires More Tuning:
transition_cov is critical❌ Not Ideal for Stationary Data: Use NimbusLDA if data is stable
❌ Memory: Maintains state history (minimal overhead)
Model Selection Context
UseNimbusSTS when prediction quality degrades over a long session, across days, or after electrode/user-state drift. Static models (NimbusLDA, NimbusQDA, NimbusSoftmax, NimbusProbit) are usually simpler and faster for stable sessions.
Rule of thumb: If accuracy degrades by more than 10% from start to end of session, evaluate NimbusSTS.
For the canonical side-by-side comparison, see Model Specification.
Practical Examples
Example 1: Detecting and Adapting to Drift
Example 2: Cross-Day Transfer Learning
Example 3: Real-Time Adaptive BCI Loop
Next Read
Bayesian LDA (NimbusLDA)
Faster static model for stationary data
Bayesian QDA (NimbusQDA)
Static model with class-specific covariances
Python SDK Streaming
Real-time streaming with NimbusSTS
Advanced Applications
Complete tutorials and use cases
References
Implementation:- Extended Kalman Filter: https://en.wikipedia.org/wiki/Extended_Kalman_filter
- Source code:
/nimbus_bci/models/nimbus_sts/in nimbus-bci
- Durbin, J., & Koopman, S. J. (2012). “Time Series Analysis by State Space Methods”
- Harvey, A. C. (1990). “Forecasting, Structural Time Series Models and the Kalman Filter”
- Särkkä, S. (2013). “Bayesian Filtering and Smoothing”
- Vidaurre, C., et al. (2011). “Co-adaptive calibration to improve BCI efficiency”
- Shenoy, P., et al. (2006). “Towards adaptive classification for BCI”
- Kirchner, E. A., et al. (2013). “On the applicability of brain reading for predictive human-machine interfaces in robotics”