Metadata-Version: 2.4
Name: sphere-ser
Version: 0.1.0
Summary: SPHERE: Single-Pass Hierarchical Effort-Robust Estimator — psychoacoustically grounded feature scaler for Speech Emotion Recognition
Author: SPHERE Research Team
License-Expression: LicenseRef-Proprietary
Keywords: speech-emotion-recognition,feature-scaling,MFCC,TKEO,psychoacoustics,scikit-learn
Classifier: Development Status :: 3 - Alpha
Classifier: Intended Audience :: Science/Research
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.8
Classifier: Programming Language :: Python :: 3.9
Classifier: Programming Language :: Python :: 3.10
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
Classifier: Topic :: Multimedia :: Sound/Audio :: Analysis
Requires-Python: >=3.8
Description-Content-Type: text/markdown
License-File: LICENSE
Requires-Dist: numpy>=1.21
Requires-Dist: scipy>=1.7
Requires-Dist: scikit-learn>=1.0
Provides-Extra: dev
Requires-Dist: pytest>=7.0; extra == "dev"
Requires-Dist: pytest-cov>=4.0; extra == "dev"
Requires-Dist: ruff>=0.1; extra == "dev"
Requires-Dist: mypy>=1.0; extra == "dev"
Provides-Extra: examples
Requires-Dist: librosa>=0.10; extra == "examples"
Requires-Dist: matplotlib>=3.5; extra == "examples"
Dynamic: license-file

# sphere-ser

**SPHERE** — Single-Pass Hierarchical Effort-Robust Estimator

A psychoacoustically grounded, sklearn-compatible feature scaler for
**Speech Emotion Recognition (SER)**.

```bash
pip install sphere-ser
```

---

## Why SPHERE?

Existing scalers treat all frames and feature dimensions uniformly.
Emotional speech breaks every assumption they make:

| Problem | Existing scalers | SPHERE |
|---|---|---|
| High-energy emotion frames distort statistics | Ignored | Energy-weighted P² median |
| MFCC distributions are right/left-skewed | Symmetric | Asymmetric σ⁺ / σ⁻ |
| All frequency bands treated equally | None | Bark-ERB perceptual gain γ_f |
| Outlier arousal peaks break StandardScaler | Breakdown ε*→0 | ε* = ½ (centre) |
| Expensive rolling median | O(T log T) | O(1) per sample via P² |

---

## Quick Start

```python
import numpy as np
from sphere_ser import SPHERE

X_train = np.random.randn(200, 40)   # (T frames, F features)
X_test  = np.random.randn(50,  40)

scaler = SPHERE(sample_rate=22050)
X_train_scaled = scaler.fit_transform(X_train)
X_test_scaled  = scaler.transform(X_test)
```

### sklearn Pipeline

```python
from sklearn.pipeline import Pipeline
from sklearn.svm import SVC
from sphere_ser import SPHERE

pipe = Pipeline([
    ('sphere', SPHERE(sample_rate=22050)),
    ('clf',    SVC(kernel='rbf', class_weight='balanced')),
])
pipe.fit(X_train_feats, y_train)
preds = pipe.predict(X_test_feats)
```

### Inspect fitted statistics

```python
scaler = SPHERE().fit(X_train)
print(scaler.feature_summary())
# SPHERE fitted on 200 frames × 40 features
#   Median range  : [-0.31, 0.42]
#   σ⁺ range      : [0.08, 1.43]
#   σ⁻ range      : [0.07, 1.22]
#   Bark γ range  : [0.98, 1.27]
#   Asymmetry (ρ) : right=18  sym≈14  left=8

stats = scaler.get_statistics()
# Keys: medians, sigma_plus, sigma_minus, bark_gains, asymmetry_ratio,
#       n_features, n_samples

print("Right-skewed features:", (stats['asymmetry_ratio'] > 1.2).sum())
```

---

## Algorithm

```
Offline  │  Bark-ERB gain γ_f     O(F)    precomputed once
─────────┼───────────────────────────────────────────────────
Pass 1   │  P² streaming median   O(TF)   O(5F) memory
Pass 2   │  Centred TKEO ψ_c      O(TF)   O(F)  memory
         │  Asymmetric σ⁺, σ⁻    O(TF)
         │  SPHERE transform      O(TF)
```

**Core transform** for each sample (t, f):

```
x̃(t,f) = γ_f · (x(t,f) − m̂_f) / (σ̂_asym(t,f) + ε)

  σ̂_asym = σ̂⁺_ψ(f)  if x(t,f) > m̂_f
           σ̂⁻_ψ(f)  otherwise
```

| Component | Purpose | Ref |
|---|---|---|
| **P² median** | O(1)-per-sample robust centre; ε* = ½ | Jain & Chlamtac 1985 |
| **Centred TKEO** | Effort-spread A²ω² per feature trajectory | Teager 1980 |
| **Asymmetric σ⁺/σ⁻** | Adapts to skewness of emotional distributions | Novel |
| **Bark-ERB gain γ_f** | Cochlear frequency resolution weighting | Zwicker 1980 |

---

## Standalone Components

```python
from sphere_ser import P2Quantile, BarkGain, TKEO, centred_tkeo, bark_gain

# P² streaming quantile
p2 = P2Quantile(n_features=40, p=0.5)
for frame in X:
    p2.update(frame)
medians = p2.estimate()          # (40,)

# Bark-ERB gain
bg = BarkGain(sample_rate=22050)
gains = bg.compute(n_features=40)               # (40,)
freqs = bg.centre_frequencies(n_features=40)    # Hz per coeff
bws   = bg.critical_bandwidths(n_features=40)   # Bark BW per coeff

# Centred TKEO
import numpy as np
psi_c = centred_tkeo(X, medians)                # (T-2, F)

# Asymmetric TKEO spread
op = TKEO(clip_factor=9.0)
psi        = op.centred(X, medians)
sig_p, sig_m = op.asymmetric_spread(X, medians, psi)
```

---

## Parameters

| Parameter | Default | Description |
|---|---|---|
| `epsilon` | `1e-8` | Numerical stability constant |
| `sample_rate` | `22050` | Sample rate (Hz) for Bark gain |
| `use_bark_gain` | `True` | Apply Bark-ERB perceptual gain |
| `clip_tkeo` | `True` | Clip TKEO at `clip_factor × σ_pilot` |
| `clip_factor` | `9.0` | TKEO clipping multiplier |
| `min_frames_fallback` | `True` | Fallback to mean/std for T < 5 |

---

## Theoretical Properties

| Property | Value |
|---|---|
| Centre breakdown point | **1/2** (optimal) |
| Scale breakdown point | **1/3** (bounded contamination) |
| Location equivariance | Exact |
| Scale equivariance | Asymptotic (ε → 0) |
| Time complexity | O(TF) |
| Memory | O(F) |

---

## Citation

```bibtex
@software{sphere_ser_2026,
  author = {{SPHERE Research Team}},
  title  = {{SPHERE}: Single-Pass Hierarchical Effort-Robust Estimator
            for Speech Emotion Recognition},
  year   = {2026},
  note   = {Proprietary Python software package}
}
```

---

## License

Proprietary software — see [LICENSE](LICENSE) for terms and conditions.
