> ## Documentation Index
> Fetch the complete documentation index at: https://docs.nimbusbci.com/llms.txt
> Use this file to discover all available pages before exploring further.

# BCI Feature Normalization

> Normalize BCI features consistently across training, testing, and deployment to improve cross-session reliability.

# Feature Normalization For BCI

Feature normalization keeps calibration, evaluation, and deployment data on the same scale. It is especially important for cross-session BCI, where electrode impedance, skin conductance, amplifier gain, and user state can shift feature amplitudes.

<Warning>
  Estimate normalization parameters from training or calibration data only. Reuse those exact parameters for test and deployment data.
</Warning>

## When To Normalize

Normalize when:

* using a model across sessions or days
* combining subjects or recording systems
* mixing feature families with different scales
* running long sessions where electrode/contact quality may drift

Do not normalize raw EEG before feature extraction. Extract CSP, bandpower, ERP, or other features first.

## Recommended Workflow

<Tabs>
  <Tab title="Python">
    ```python theme={null}
    from nimbus_bci import estimate_normalization_params, apply_normalization

    norm = estimate_normalization_params(X_train, method="zscore")

    X_train_norm = apply_normalization(X_train, norm)
    X_test_norm = apply_normalization(X_test, norm)

    clf.fit(X_train_norm, y_train)
    predictions = clf.predict(X_test_norm)
    ```
  </Tab>

  <Tab title="Julia">
    ```julia theme={null}
    using NimbusSDK

    norm = estimate_normalization_params(train_features; method=:zscore)

    train_norm = apply_normalization(train_features, norm)
    test_norm = apply_normalization(test_features, norm)

    train_data = BCIData(train_norm, metadata, train_labels)
    model = train_model(NimbusLDA, train_data)

    results = predict_batch(model, BCIData(test_norm, metadata, test_labels))
    ```
  </Tab>
</Tabs>

## Method Choice

| Method   | Use When                            | Tradeoff                       |
| -------- | ----------------------------------- | ------------------------------ |
| `zscore` | Default BCI workflow                | Sensitive to extreme outliers. |
| `robust` | Noisy data with artifacts           | Less standard, more resilient. |
| `minmax` | Bounded feature ranges are required | Very sensitive to outliers.    |

Start with `zscore`. Switch to `robust` when artifacts or heavy-tailed features make mean/std unstable.

## Common Pitfalls

* **Normalizing train and test separately**: causes scale leakage and unstable evaluation.
* **Normalizing raw EEG**: can break feature extraction assumptions.
* **Forgetting to save parameters**: makes deployment data incompatible with training scale.
* **Changing preprocessing after calibration**: invalidates the saved normalization parameters.

## What To Save

Save normalization parameters next to the model:

```json theme={null}
{
  "normalization": "zscore",
  "estimated_from": "training-session-001",
  "feature_type": "csp",
  "n_features": 8
}
```

Also save the SDK version, feature extraction settings, label mapping, and validation metrics.

## Quality Checks

Before inference:

* feature values are finite
* feature count matches model metadata
* normalization params came from training/calibration data
* test/deployment data used the same preprocessing pipeline

If confidence drops unexpectedly, run preprocessing diagnostics and inspect whether feature scale changed between sessions.

## Next Read

<CardGroup cols={2}>
  <Card title="Preprocessing Requirements" icon="list-filter" href="/inference-configuration/preprocessing-requirements">
    Prepare valid features before normalization.
  </Card>

  <Card title="External Preprocessing Integration" icon="link" href="/development/preprocessing-integration">
    Export/import feature arrays across tools.
  </Card>

  <Card title="Batch Processing" icon="list" href="/inference-configuration/batch-processing">
    Offline evaluation with normalized data.
  </Card>

  <Card title="Error Handling" icon="shield" href="/inference-configuration/error-handling">
    Diagnose bad scale, shape, or confidence.
  </Card>
</CardGroup>
