Bayesian QDA (NimbusQDA)
Python:NimbusQDA | Julia: NimbusQDAMathematical Model: Heteroscedastic Gaussian Classifier (HGC) NimbusQDA is a Bayesian classification model with class-specific covariance matrices, making it more flexible than NimbusLDA for modeling complex class distributions.
Python Personalizer head: use as
Personalizer(head="qda"), or standalone as NimbusQDA. See Personalizer & Middleware.Available in Both SDKs:
- Python SDK:
NimbusQDAclass (sklearn-compatible) - Julia SDK:
NimbusQDA(RxInfer.jl-based)
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 QDA extends beyond traditional Gaussian classifiers by allowing each class to have its own covariance structure: ✅ Class-specific covariances (unlike Bayesian LDA’s shared covariance)✅ More flexible modeling of heterogeneous distributions
✅ Posterior probability distributions with uncertainty quantification
✅ Fast inference (~15-25ms per trial)
✅ Training and calibration support
✅ Batch and streaming inference modes
Quick Start
- Python
- Julia
When to Use Bayesian QDA
Bayesian QDA is ideal for:- Complex, overlapping class distributions
- Classes with significantly different variances
- P300 detection (target/non-target with different spreads)
- When Bayesian LDA accuracy is unsatisfactory
- When you need maximum flexibility
- Classes are well-separated and have similar spreads
- Speed is critical (Bayesian LDA is faster)
- Training data is limited (Bayesian LDA needs less data)
- Memory is constrained (Bayesian LDA uses less memory)
Model Architecture
Mathematical Foundation (Heteroscedastic Gaussian Classifier)
Bayesian QDA implements a Heteroscedastic Gaussian Classifier (HGC), which models class-conditional distributions with class-specific precision matrices:μ_k= mean vector for class kW_k= class-specific precision matrix (different for each class)- Allows different covariance structures per class
Hyperparameters
Bayesian QDA supports configurable hyperparameters for optimal performance tuning: Available Hyperparameters (training):
Parameter Effects:
-
dof_offset: Controls regularization strength
- Lower values (1) → More data-driven, less regularization
- Higher values (3-5) → More regularization, more conservative
-
mean_prior_precision: Controls prior strength on class means
- Lower values (0.001) → Weaker prior, trusts data more
- Higher values (0.05-0.1) → Stronger prior, more regularization
Model Structure
RxInfer Implementation
Learning Phase:Usage
1. Load Pre-trained Model
Python SDK: The Python SDK (
nimbus-bci) trains models locally. See Python SDK Quickstart for training examples.- Python
- Julia
2. Train Custom Model
- Python
- Julia
iterations: Number of variational inference iterations (default: 50)- More iterations = better convergence, typical range: 50-100
showprogress: Display progress bar during trainingname: Model identifierdescription: Model descriptiondof_offset: Degrees of freedom offset (default: 2, range: [1, 5])mean_prior_precision: Prior precision for means (default: 0.01, range: [0.001, 0.1])
3. Subject-Specific Calibration
- Python
- Julia
- Requires only 10-20 trials per class
- Faster than training from scratch
- Adapts to subject-specific characteristics
- Hyperparameters preserved:
calibrate_model()automatically uses the same hyperparameters as the base model (v0.2.0+)
4. Batch Inference
- Python
- Julia
5. Streaming Inference
For detailed Python streaming examples, see Python SDK Streaming Inference.
- Python
- Julia
Hyperparameter Tuning (v0.2.0+)
Fine-tune Bayesian QDA for optimal performance on your specific dataset.When to Tune Hyperparameters
Consider tuning when:- Default performance is unsatisfactory
- You have specific data characteristics (very noisy or very clean)
- You have limited or extensive training data
- Working with complex, overlapping class distributions
- P300 or other paradigms with heterogeneous class variances
Tuning Strategies
For High SNR / Clean Data / Many Trials
Use lower regularization to let the data drive the model:- Python
- Julia
- SNR > 5 dB
- 100+ trials per class
- Clean, artifact-free data
- Well-controlled experimental conditions
For Low SNR / Noisy Data / Few Trials
Use higher regularization for stability (especially important for QDA with class-specific covariances):- Python
- Julia
- SNR < 2 dB
- 40-80 trials per class
- Noisy data or limited artifact removal
- Challenging recording conditions
- Risk of overfitting to class-specific noise
Balanced / Default Settings
The defaults work well for most scenarios:- Moderate SNR (2-5 dB)
- 80-150 trials per class
- Standard BCI recording conditions
- Starting point for experimentation
P300-Specific Tuning
For P300 paradigms where target/non-target classes have different variances:Hyperparameter Search Example
Systematically search for optimal hyperparameters:Quick Tuning Guidelines
Important: Always set
predictive_dof_offset to match dof_offset for consistency between training and inference phases.Training Requirements
Data Requirements
- Minimum: 40 trials per class (80 total for 2-class)
- Recommended: 80+ trials per class
- For calibration: 10-20 trials per class
Feature Normalization
- Python
- Julia
Feature Requirements
Bayesian QDA expects preprocessed features, not raw EEG: ✅ Required preprocessing:- Bandpass filtering (paradigm-specific)
- Artifact removal
- Feature extraction (CSP, ERP amplitude, bandpower, etc.)
- Proper temporal aggregation
- Raw EEG channels
- Unfiltered data
Performance Characteristics
Computational Performance
Slightly slower than NimbusLDA due to class-specific covariances.
Classification Accuracy
Bayesian QDA typically provides 2-5% higher accuracy than Bayesian LDA when class covariances differ significantly, at the cost of ~5-10ms additional latency.
Model Inspection
View Model Parameters
- Python
- Julia
Accessing model parameters: The SDK stores full posterior distributions (not just point estimates) for proper Bayesian inference. To get point estimates, use
mean(posterior) to extract the mean of the posterior distribution. For precision matrices, use mean(precision_posterior) to get the expected precision matrix.Visualize Class Differences
Advantages & Limitations
Advantages
✅ Flexible Modeling: Each class has its own covariance✅ Better for Complex Data: Handles heterogeneous distributions
✅ Higher Accuracy: 2-5% improvement when classes differ significantly
✅ Uncertainty Quantification: Full Bayesian posteriors
✅ Production-Ready: Battle-tested in P300 applications
Limitations
❌ More Parameters: Requires more training data than NimbusLDA❌ Slower Inference: ~15-25ms vs ~10-15ms for NimbusLDA
❌ Higher Memory: Stores n_classes precision matrices
❌ More Complex: Longer training time
Model Selection Context
UseNimbusQDA when the task is stationary but classes have different spreads, covariance structure, or overlapping distributions. If speed and simple class structure matter more, start with NimbusLDA. If the boundary is non-Gaussian, consider NimbusSoftmax in Python or NimbusProbit in Julia. If class distributions drift over time, use NimbusSTS in Python.
For the canonical side-by-side comparison, see Model Specification.
Practical Examples
P300 Detection
When Bayesian LDA Fails
Next Read
Bayesian LDA (NimbusLDA)
Faster model with shared covariance
NimbusSoftmax (Python)
Python non-Gaussian static classifier for complex decision boundaries
NimbusProbit (Julia)
Julia non-Gaussian static classifier for complex decision boundaries
Bayesian STS (NimbusSTS)
Adaptive model for non-stationary data
Training Guide
Complete training tutorial
Code Examples
Working examples
References
Implementation:- RxInfer.jl: https://rxinfer.com/
- Source code:
NimbusQDAmodel implementation in NimbusSDK.jl
- Bishop, C. M. (2006). “Pattern Recognition and Machine Learning” (Quadratic discriminant analysis and Gaussian classifiers)
- Heteroscedastic Gaussian Classifier (HGC) with class-specific covariances
- Farwell, L. A., & Donchin, E. (1988). “Talking off the top of your head”
- Lotte et al. (2018). “A review of classification algorithms for EEG-based BCI”