SPHERE: Single-Pass Hierarchical Effort-Robust Estimator — psychoacoustically grounded feature scaler for Speech Emotion Recognition
Project description
sphere-ser
SPHERE — Single-Pass Hierarchical Effort-Robust Estimator
A psychoacoustically grounded, sklearn-compatible feature scaler for Speech Emotion Recognition (SER).
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
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
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
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
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
@software{sphere_ser_2026,
author = {Gumelar, A.B. and Irzan, R.M. Yusuf},
title = {{SPHERE}: Single-Pass Hierarchical Effort-Robust Estimator
for Speech Emotion Recognition},
year = {2026},
note = {Proprietary Python software package}
}
License
This project is proprietary and closed-source. All rights reserved.
Bug Reports
Please report all your bug and finding to: abgumelar.dev [at] gmail [dot] com
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file sphere_ser-0.1.2.tar.gz.
File metadata
- Download URL: sphere_ser-0.1.2.tar.gz
- Upload date:
- Size: 16.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
85dcc31eb25899df51b2eb95cc1dd27df0ff5d76159018f88d66674865b321f1
|
|
| MD5 |
c8efd3f5ab2c0894f3b2478bcbab8bdc
|
|
| BLAKE2b-256 |
436b60d4e8dd85a13f4c2ece488e9bc5268f5f7d84a7090ef9bf9a721cc5b7b2
|
File details
Details for the file sphere_ser-0.1.2-py3-none-any.whl.
File metadata
- Download URL: sphere_ser-0.1.2-py3-none-any.whl
- Upload date:
- Size: 12.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.2.0 CPython/3.12.13
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
4ccfe1ac4930ce859002a7892a4296cc7646fc9b06a7760c78fe8d1e24cbdeef
|
|
| MD5 |
74bd30abcf272c82245ddab3d568ec72
|
|
| BLAKE2b-256 |
ccfa8d47e72adff395549fc8b0a76ea0d70760c67bc7dc45fc6150c021874241
|