Skip to main content

Bayesian LDA - Bayesian Linear Discriminant Analysis

Python: NimbusLDA | Julia: NimbusLDA
Mathematical Model: Pooled Gaussian Classifier (PGC)
Bayesian LDA is a Bayesian classification model with uncertainty quantification. It uses a shared precision matrix across all classes, making it fast and efficient for BCI classification.
Python Personalizer head: use as Personalizer(head="lda") (default), or standalone as NimbusLDA. See Personalizer & Middleware.
Available in Both SDKs:
  • Python SDK: NimbusLDA class (sklearn-compatible)
  • Julia SDK: NimbusLDA (RxInfer.jl-based)
Both implementations provide the same Bayesian inference with uncertainty quantification.

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 LDA extends traditional Linear Discriminant Analysis with full Bayesian inference, providing: ✅ Posterior probability distributions (not just point estimates)
Uncertainty quantification for each prediction
Probabilistic confidence scores
Fast inference (<20ms per trial)
Training and calibration support
Batch and streaming inference modes

Quick Start

When to Use Bayesian LDA

Bayesian LDA is ideal for:
  • Motor Imagery classification (2-4 classes)
  • Well-separated class distributions
  • Fast inference requirements (<20ms)
  • Interpretable results for medical applications
  • When classes have similar covariance structures
Consider Bayesian QDA instead if:
  • Classes have significantly different covariance structures
  • Complex, overlapping distributions
  • Need more flexibility in modeling per-class variances

Model Architecture

Mathematical Foundation (Pooled Gaussian Classifier)

Bayesian LDA implements a Pooled Gaussian Classifier (PGC), which models class-conditional distributions with a shared precision matrix:
Where:
  • μ_k = mean vector for class k (learned from data)
  • W = shared precision matrix (same for all classes)
  • Assumes classes have similar covariance structure
Key Assumption: All classes share the same covariance structure, which makes training and inference faster.

Hyperparameters

Bayesian LDA 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

The Bayesian LDA model uses RxInfer.jl for variational Bayesian inference: Learning Phase:
Prediction Phase (Mixture Likelihood): Inference uses the learned posterior distributions as priors in a mixture model:
The trained mean and precision posteriors are supplied through RxInfer initialization so uncertainty is carried into prediction.

Usage

1. Load Pre-trained Model

Python SDK: The Python SDK (nimbus-bci) trains models locally and doesn’t require pre-trained model loading. See Python SDK Quickstart for training examples.

2. Train Custom Model

Training Parameters:
  • iterations: Number of variational inference iterations (default: 50)
    • More iterations = better convergence but slower training
    • 50-100 is typically sufficient
  • showprogress: Display progress bar during training
  • name: Model identifier
  • description: Model description for documentation
  • dof_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

Fine-tune a pre-trained model with subject-specific data (much faster than training from scratch):
Calibration Benefits:
  • Requires only 10-20 trials per class (vs 50-100 for training from scratch)
  • Faster: 20 iterations vs 50-100
  • Better generalization: Uses pre-trained model as prior
  • Typical accuracy improvement: 5-15% over generic model
  • Hyperparameters automatically preserved: calibrate_model() inherits training hyperparameters from the base model (dof_offset, mean_prior_precision) ensuring consistency
Important: You don’t need to specify hyperparameters when calibrating - they are automatically inherited from the base model. This ensures the calibrated model uses the same regularization strategy that worked well during initial training.

4. Batch Inference

Process multiple trials efficiently:

5. Streaming Inference

Real-time chunk-by-chunk processing:
For detailed Python streaming examples, see Python SDK Streaming Inference.

Hyperparameter Tuning (v0.2.0+)

Fine-tune Bayesian LDA 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
  • You want to optimize for your specific paradigm

Tuning Strategies

For High SNR / Clean Data / Many Trials

Use lower regularization to let the data drive the model:
Use when:
  • 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:
Use when:
  • SNR < 2 dB
  • 40-80 trials per class
  • Noisy data or limited artifact removal
  • Challenging recording conditions

Balanced / Default Settings

The defaults work well for most scenarios:
Use when:
  • Moderate SNR (2-5 dB)
  • 80-150 trials per class
  • Standard BCI recording conditions
  • Starting point for experimentation

Hyperparameter Search Example

Systematically search for optimal hyperparameters:

Quick Tuning Guidelines

Pro Tip: Start with defaults (dof_offset=2, mean_prior_precision=0.01) and only tune if performance is unsatisfactory. The defaults are optimized for typical BCI scenarios.

Training Requirements

Data Requirements

  • Minimum: 40 trials per class (160 total for 4-class)
  • Recommended: 80+ trials per class (320+ total for 4-class)
  • For calibration: 10-20 trials per class sufficient
Bayesian LDA requires at least 2 trials to estimate class statistics and shared precision matrix. Single-trial training is not statistically valid for LDA and will raise an ArgumentError.Your training data must have shape (n_features, n_samples, n_trials) where n_trials >= 2.

Feature Normalization

Critical for cross-session BCI performance!Normalize your features before training for 15-30% accuracy improvement across sessions.
See Feature Normalization for the recommended train/test scaling workflow.

Feature Requirements

Bayesian LDA expects preprocessed features, not raw EEG: Required preprocessing:
  • Bandpass filtering (8-30 Hz for motor imagery)
  • Artifact removal (ICA recommended)
  • Spatial filtering (CSP for motor imagery)
  • Feature extraction (log-variance for CSP features)
  • Temporal aggregation (handled automatically during training/inference)
NOT accepted:
  • Raw EEG channels
  • Unfiltered data
  • Non-extracted features
See Preprocessing Requirements for details.

Temporal Aggregation

Critical Preprocessing Step: Before training, the SDK automatically aggregates the temporal dimension of each trial into a single feature vector. This prevents treating temporally correlated samples as independent observations, which would violate the i.i.d. assumption of the model.
The aggregation method depends on your feature type and paradigm:
  • CSP features: Log-variance aggregation (default for motor imagery)
  • Power spectral features: Mean or median aggregation
  • Other features: Configurable via BCIMetadata.temporal_aggregation
This aggregation happens automatically during train_model() and predict_batch() calls.

Performance Characteristics

Computational Performance

All measurements on standard CPU (no GPU required).

Classification Accuracy

Accuracy is highly subject-dependent. Subject-specific calibration typically improves accuracy by 5-15%.

Model Inspection

View Model Parameters

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.

Compare Models

Advantages & Limitations

Advantages

Fast Training: Shared covariance estimation is efficient
Fast Inference: Analytical posterior computation (<20ms)
Interpretable: Clear probabilistic formulation
Memory Efficient: Single shared precision matrix
Robust: Handles uncertainty naturally via Bayesian inference
Production-Ready: Battle-tested in real BCI applications

Limitations

Shared Covariance Assumption: May not fit well if classes have very different spreads
Linear Decision Boundary: Cannot capture non-linear class boundaries
Gaussian Assumption: Assumes normal class distributions
Not Ideal for Overlapping Classes: Use NimbusQDA for complex distributions

Model Selection Context

Use NimbusLDA when classes are mostly stationary and well separated, and speed or interpretability matter. If classes overlap with different covariance structure, consider NimbusQDA. If the decision boundary is non-Gaussian, consider NimbusSoftmax in Python or NimbusProbit in Julia. If distributions drift over time, consider NimbusSTS in Python. For the canonical side-by-side comparison, see Model Specification.

Next Read

Bayesian QDA (NimbusQDA)

More flexible classifier with class-specific covariances

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 and long sessions

Training Tutorial

Complete training walkthrough

Code Examples

Working examples

References

Implementation: Theory:
  • Fisher, R. A. (1936). “The use of multiple measurements in taxonomic problems”
  • Bishop, C. M. (2006). “Pattern Recognition and Machine Learning” (Chapter 4)
  • Pooled Gaussian Classifier (PGC) with shared covariance structure
BCI Applications:
  • Blankertz et al. (2008). “Optimizing spatial filters for robust EEG single-trial analysis”
  • Lotte et al. (2018). “A review of classification algorithms for EEG-based BCI”