bioamla.cluster¶
bioamla.cluster ¶
Clustering, dimensionality reduction, and novel-sound discovery.
Cluster audio embeddings (HDBSCAN, k-means, DBSCAN, agglomerative), reduce embedding dimensionality (UMAP, t-SNE, PCA), measure cluster quality, and detect novel/outlier sounds.
Heavy backends (umap-learn, hdbscan, scikit-learn, torch) ship in the base install but are imported lazily so importing this module stays fast.
Example
import numpy as np from bioamla.cluster import AudioClusterer, reduce_dimensions emb = np.random.rand(100, 32) reduced = reduce_dimensions(emb, method="pca", n_components=2) labels = AudioClusterer(method="kmeans").fit_predict(reduced)
AudioClusterer ¶
Clustering for audio embeddings.
Supports multiple clustering algorithms with automatic parameter tuning.
__init__ ¶
__init__(
config: ClusteringConfig | None = None,
method: str | None = None,
**kwargs: Any,
) -> None
Initialize clusterer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
config
|
ClusteringConfig | None
|
Clustering configuration |
None
|
method
|
str | None
|
Clustering method (overrides config) |
None
|
**kwargs
|
Any
|
Additional arguments for the clusterer |
{}
|
get_cluster_centers ¶
get_cluster_centers(embeddings: ndarray) -> np.ndarray
Compute cluster centers from embeddings.
get_cluster_stats ¶
get_cluster_stats(
embeddings: ndarray,
) -> dict[int, dict[str, Any]]
Get statistics for each cluster.
ClusteringConfig
dataclass
¶
Configuration for clustering.
IncrementalReducer ¶
Incremental dimensionality reducer for streaming data.
Fits on initial data and can transform new points without refitting.
__init__ ¶
__init__(
method: str = "umap",
n_components: int = 2,
**kwargs: Any,
) -> None
Initialize incremental reducer.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
method
|
str
|
Reduction method ("umap" or "pca") |
'umap'
|
n_components
|
int
|
Number of output dimensions |
2
|
**kwargs
|
Any
|
Additional arguments for the reducer |
{}
|
NoveltyDetector ¶
Detect novel sound types in audio embeddings.
Uses distance-based and density-based methods to identify sounds that don't fit existing clusters.
__init__ ¶
__init__(
method: str = "distance",
threshold: float | None = None,
contamination: float = 0.1,
) -> None
Initialize novelty detector.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
method
|
str
|
Detection method ("distance", "isolation_forest", "lof") |
'distance'
|
threshold
|
float | None
|
Novelty threshold (auto-computed if None) |
None
|
contamination
|
float
|
Expected proportion of outliers |
0.1
|
fit ¶
fit(
embeddings: ndarray, labels: ndarray | None = None
) -> NoveltyDetector
Fit the novelty detector.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
embeddings
|
ndarray
|
Training embeddings (known sounds) |
required |
labels
|
ndarray | None
|
Optional cluster labels |
None
|
Returns:
| Type | Description |
|---|---|
NoveltyDetector
|
self |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
If the method is unknown. |
predict ¶
predict(embeddings: ndarray) -> list[NoveltyResult]
Detect novel sounds in new embeddings.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
embeddings
|
ndarray
|
Embeddings to check for novelty |
required |
Returns:
| Type | Description |
|---|---|
list[NoveltyResult]
|
List of NoveltyResult for each embedding |
get_novel_samples ¶
get_novel_samples(
embeddings: ndarray, n_samples: int | None = None
) -> list[int]
Get indices of most novel samples.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
embeddings
|
ndarray
|
Embeddings to check |
required |
n_samples
|
int | None
|
Number of novel samples to return (all if None) |
None
|
Returns:
| Type | Description |
|---|---|
list[int]
|
Indices of novel samples, sorted by novelty score |
NoveltyResult
dataclass
¶
Result from novelty detection.
ReductionConfig
dataclass
¶
Configuration for dimensionality reduction.
ClusterAnalysis
dataclass
¶
Detailed cluster analysis results.
ClusteringSummary
dataclass
¶
Summary of clustering results.
NoveltyDetectionSummary
dataclass
¶
Summary of novelty detection results.
ClusteringError ¶
Bases: BioamlaError
A clustering, dimensionality-reduction, or novelty-detection failure.
DependencyError ¶
Bases: BioamlaError
A required dependency is unavailable at runtime.
All Python dependencies ship in the base install, so this is reserved for genuine environment problems (e.g. a missing system library or a broken install).
cluster_batch_files ¶
cluster_batch_files(
input_dir: str | Path,
output_dir: str | Path,
*,
method: str = "hdbscan",
n_clusters: int | None = None,
min_cluster_size: int = 5,
min_samples: int = 3,
recursive: bool = True,
continue_on_error: bool = True,
**kwargs: Any,
) -> BatchResult
Cluster all embedding files under a directory (two-phase).
Discovers embedding files under input_dir and delegates to
:func:cluster_embedding_files.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_dir
|
str | Path
|
Directory containing embedding files. |
required |
output_dir
|
str | Path
|
Directory where |
required |
method
|
str
|
Clustering method ("hdbscan", "kmeans", "dbscan", "agglomerative"). |
'hdbscan'
|
n_clusters
|
int | None
|
Number of clusters (for k-means/agglomerative). |
None
|
min_cluster_size
|
int
|
Minimum cluster size (for HDBSCAN). |
5
|
min_samples
|
int
|
Minimum samples per cluster. |
3
|
recursive
|
bool
|
Whether to recurse into subdirectories. |
True
|
continue_on_error
|
bool
|
Keep going when an individual file fails to load. |
True
|
**kwargs
|
Any
|
Additional arguments forwarded to the clusterer. |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
BatchResult
|
class: |
BatchResult
|
|
cluster_embedding_files ¶
cluster_embedding_files(
files: list[str | Path],
output_dir: str | Path,
*,
method: str = "hdbscan",
n_clusters: int | None = None,
min_cluster_size: int = 5,
min_samples: int = 3,
continue_on_error: bool = True,
**kwargs: Any,
) -> BatchResult
Cluster an explicit list of embedding files (two-phase).
Phase 1 loads each embedding file (tracked via :func:bioamla.batch.run_batch
so per-file failures are recorded). Phase 2 concatenates the successfully
loaded embeddings, clusters them once, maps labels back to files and writes
<output_dir>/cluster_assignments.json.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
files
|
list[str | Path]
|
Explicit list of embedding file paths. |
required |
output_dir
|
str | Path
|
Directory where |
required |
method
|
str
|
Clustering method ("hdbscan", "kmeans", "dbscan", "agglomerative"). |
'hdbscan'
|
n_clusters
|
int | None
|
Number of clusters (for k-means/agglomerative). |
None
|
min_cluster_size
|
int
|
Minimum cluster size (for HDBSCAN). |
5
|
min_samples
|
int
|
Minimum samples per cluster. |
3
|
continue_on_error
|
bool
|
Keep going when an individual file fails to load. |
True
|
**kwargs
|
Any
|
Additional arguments forwarded to the clusterer. |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
BatchResult
|
class: |
load_embedding_file ¶
load_embedding_file(file_path: str | Path) -> np.ndarray
Load a single embedding file as a 2D array.
Supports .npy, .pkl/.pickle and .json. 1D arrays are
reshaped to (1, n_features) and arrays of rank > 2 are flattened to
(n_samples, n_features).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
file_path
|
str | Path
|
Path to the embedding file. |
required |
Returns:
| Type | Description |
|---|---|
ndarray
|
Embedding array of shape (n_samples, n_features). |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
If the file extension is unsupported. |
load_embeddings_batch ¶
load_embeddings_batch(
input_dir: str | Path, *, recursive: bool = True
) -> tuple[list[np.ndarray], list[str]]
Phase 1: discover and load every embedding file under input_dir.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
input_dir
|
str | Path
|
Directory to search for embedding files. |
required |
recursive
|
bool
|
Whether to recurse into subdirectories. |
True
|
Returns:
| Type | Description |
|---|---|
list[ndarray]
|
Tuple |
list[str]
|
paths, in matching order. |
analyze_clusters ¶
analyze_clusters(
embeddings: ndarray,
labels: ndarray,
metadata: list[dict[str, Any]] | None = None,
) -> dict[str, Any]
Comprehensive cluster analysis.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
embeddings
|
ndarray
|
Input embeddings |
required |
labels
|
ndarray
|
Cluster labels |
required |
metadata
|
list[dict[str, Any]] | None
|
Optional metadata for each sample |
None
|
Returns:
| Type | Description |
|---|---|
dict[str, Any]
|
Analysis results as a dictionary |
analyze_clusters_summary ¶
analyze_clusters_summary(
embeddings: ndarray,
labels: ndarray,
filepaths: list[str] | None = None,
) -> ClusterAnalysis
Perform detailed analysis of clustering results and return a dataclass.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
embeddings
|
ndarray
|
Input embeddings |
required |
labels
|
ndarray
|
Cluster labels |
required |
filepaths
|
list[str] | None
|
Optional list of file paths for per-cluster metadata |
None
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
ClusterAnalysis
|
class: |
cluster_embeddings ¶
cluster_embeddings(
embeddings: ndarray,
method: str = "hdbscan",
n_clusters: int | None = None,
min_cluster_size: int = 5,
min_samples: int = 3,
**kwargs: Any,
) -> ClusteringSummary
Cluster embeddings and return a summary.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
embeddings
|
ndarray
|
Input embeddings of shape (n_samples, n_features) |
required |
method
|
str
|
Clustering method ("hdbscan", "kmeans", "dbscan", "agglomerative") |
'hdbscan'
|
n_clusters
|
int | None
|
Number of clusters (for k-means/agglomerative) |
None
|
min_cluster_size
|
int
|
Minimum cluster size (for HDBSCAN) |
5
|
min_samples
|
int
|
Minimum samples per cluster |
3
|
**kwargs
|
Any
|
Additional arguments forwarded to the clusterer constructor |
{}
|
Returns:
| Name | Type | Description |
|---|---|---|
A |
ClusteringSummary
|
class: |
ClusteringSummary
|
cluster assignments. |
Raises:
| Type | Description |
|---|---|
ClusteringError
|
If clustering fails for any other reason. |
compute_cluster_similarity ¶
compute_cluster_similarity(
embeddings: ndarray,
labels: ndarray,
metric: str = "cosine",
) -> np.ndarray
Compute pairwise similarity between clusters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
embeddings
|
ndarray
|
Input embeddings |
required |
labels
|
ndarray
|
Cluster labels |
required |
metric
|
str
|
Distance metric ("cosine", "euclidean") |
'cosine'
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Similarity matrix of shape (n_clusters, n_clusters) |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
If the metric is unknown. |
detect_novelty ¶
detect_novelty(
embeddings: ndarray,
known_embeddings: ndarray | None = None,
known_labels: ndarray | None = None,
method: str = "distance",
threshold: float | None = None,
contamination: float = 0.1,
) -> tuple[NoveltyDetectionSummary, np.ndarray, np.ndarray]
Detect novel/outlier samples in embeddings.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
embeddings
|
ndarray
|
Embeddings to check for novelty |
required |
known_embeddings
|
ndarray | None
|
Optional known embeddings to fit the detector on |
None
|
known_labels
|
ndarray | None
|
Optional labels for known embeddings |
None
|
method
|
str
|
Detection method ("distance", "isolation_forest", "lof") |
'distance'
|
threshold
|
float | None
|
Novelty threshold (auto if None) |
None
|
contamination
|
float
|
Expected proportion of outliers |
0.1
|
Returns:
| Type | Description |
|---|---|
NoveltyDetectionSummary
|
Tuple of |
ndarray
|
boolean array and |
discover_novel_sounds ¶
discover_novel_sounds(
embeddings: ndarray,
known_labels: ndarray | None = None,
method: str = "distance",
threshold: float | None = None,
return_scores: bool = False,
) -> np.ndarray | tuple[np.ndarray, np.ndarray]
Discover novel sound types in embeddings.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
embeddings
|
ndarray
|
All embeddings to analyze |
required |
known_labels
|
ndarray | None
|
Labels for known sounds (None = all unknown) |
None
|
method
|
str
|
Detection method |
'distance'
|
threshold
|
float | None
|
Novelty threshold |
None
|
return_scores
|
bool
|
Whether to return novelty scores |
False
|
Returns:
| Type | Description |
|---|---|
ndarray | tuple[ndarray, ndarray]
|
Binary array indicating novel sounds (and optionally scores) |
export_clusters ¶
export_clusters(
labels: ndarray,
filepaths: list[str],
output_dir: str,
copy_files: bool = False,
) -> str
Export clustering results to directory structure.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
labels
|
ndarray
|
Cluster labels |
required |
filepaths
|
list[str]
|
List of file paths |
required |
output_dir
|
str
|
Output directory |
required |
copy_files
|
bool
|
Whether to copy files to cluster directories |
False
|
Returns:
| Type | Description |
|---|---|
str
|
Path to output directory |
export_clusters_to_csv ¶
export_clusters_to_csv(
labels: ndarray,
filepaths: list[str],
output_path: str,
reduced_embeddings: ndarray | None = None,
) -> str
Export clustering results to a CSV file.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
labels
|
ndarray
|
Cluster labels |
required |
filepaths
|
list[str]
|
List of file paths |
required |
output_path
|
str
|
Output CSV path |
required |
reduced_embeddings
|
ndarray | None
|
Optional 2D coordinates to include as |
None
|
Returns:
| Type | Description |
|---|---|
str
|
Path to the written CSV file. |
extract_embeddings_batch ¶
extract_embeddings_batch(
model: Any,
dataloader: Any,
device: Any = None,
layer_name: str | None = None,
) -> np.ndarray
Extract embeddings from a model for a batch of data.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model
|
Any
|
PyTorch model |
required |
dataloader
|
Any
|
DataLoader with audio data |
required |
device
|
Any
|
Device to use |
None
|
layer_name
|
str | None
|
Name of layer to extract (uses last hidden if None) |
None
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Embeddings array of shape (n_samples, embedding_dim) |
find_optimal_clusters ¶
find_optimal_clusters(
embeddings: ndarray,
method: str = "silhouette",
k_range: tuple[int, int] = (2, 20),
) -> int
Find optimal number of clusters.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
embeddings
|
ndarray
|
Input embeddings |
required |
method
|
str
|
Method for determining optimal k ("silhouette", "elbow", "gap") |
'silhouette'
|
k_range
|
tuple[int, int]
|
Range of k values to try |
(2, 20)
|
Returns:
| Type | Description |
|---|---|
int
|
Optimal number of clusters |
reduce_dimensions ¶
reduce_dimensions(
embeddings: ndarray,
config: ReductionConfig | None = None,
method: str | None = None,
n_components: int = 2,
random_state: int = 42,
**kwargs: Any,
) -> np.ndarray
Reduce dimensionality of embeddings.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
embeddings
|
ndarray
|
Input embeddings of shape (n_samples, n_features) |
required |
config
|
ReductionConfig | None
|
Reduction configuration |
None
|
method
|
str | None
|
Reduction method (overrides config) |
None
|
n_components
|
int
|
Number of output dimensions |
2
|
random_state
|
int
|
Random seed |
42
|
**kwargs
|
Any
|
Additional arguments for the reducer |
{}
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Reduced embeddings of shape (n_samples, n_components) |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
If the reduction method is unknown. |
sort_by_similarity ¶
sort_by_similarity(
embeddings: ndarray,
reference: ndarray | None = None,
method: str = "nearest_neighbor",
) -> np.ndarray
Sort embeddings by similarity.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
embeddings
|
ndarray
|
Input embeddings |
required |
reference
|
ndarray | None
|
Reference embedding (uses first embedding if None) |
None
|
method
|
str
|
Sorting method ("nearest_neighbor", "spectral") |
'nearest_neighbor'
|
Returns:
| Type | Description |
|---|---|
ndarray
|
Sorted indices |
Raises:
| Type | Description |
|---|---|
InvalidInputError
|
If the method is unknown. |
sort_clusters_by_similarity ¶
sort_clusters_by_similarity(
embeddings: ndarray,
labels: ndarray,
reference_label: int | None = None,
) -> list[int]
Sort cluster labels by similarity to each other.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
embeddings
|
ndarray
|
Input embeddings |
required |
labels
|
ndarray
|
Cluster labels |
required |
reference_label
|
int | None
|
Starting cluster (uses largest if None) |
None
|
Returns:
| Type | Description |
|---|---|
list[int]
|
Sorted list of cluster labels |