Skip to article frontmatterSkip to article content
Site not loading correctly?

This may be due to an incorrect BASE_URL configuration. See the MyST Documentation for reference.

Authored by Souvik Mandal, Ph.D.

Project Leader & Instructor, Computational Behavioral Sciences, LS100, FAS, Harvard University | Linkedin ID: souvik-mandal-phd


In this notebook, we will:

  1. Take a folder of audio files (e.g., songs or stems).

  2. For each track, compute a compact acoustic embedding using:

    • Mel-spectrogram statistics (how energy is distributed across frequency)

    • MFCC statistics (a classic timbre representation)

    • Spectral features (centroid, bandwidth, rolloff, flatness, RMS, zero-crossing rate)

  3. Stack these embeddings into a feature matrix (one vector per track).

  4. Run two clustering methods:

    • k-means (you choose the number of clusters)

    • HDBSCAN (finds clusters and outliers automatically)

The acoustic embedding is a fixed-length numeric vector that summarizes the “sound fingerprint” of a track.
We will use these vectors as inputs for clustering (k-means & HDBSCAN).

Last updated: 2026-07-02

Open in Colab Open in GitHub Codespaces

Install dependencies

Imports and configuration

Step 1 — Imports and configuration

We will:

  • Import librosa for audio feature extraction.

  • Import NumPy / pandas for numerical work and tables.

  • Import scikit-learn for k-means and scaling.

  • Import HDBSCAN for density-based clustering.

  • Set the folder that contains our audio files.

In Colab, you can either:

  • Upload audio files directly, or

  • Mount Google Drive and point AUDIO_FOLDER to a folder in your Drive.

Imports and configuration

librosa version: 0.11.0
Audio folder: /Users/souvikmandal/Documents/06_Teaching_Mentoring/LS100_comp_etho/2025/media/audio/music_tracks/Audio_Clips

Helper: list files and quick check

We’ll search the folder (and subfolders) for common audio extensions and make sure we have files to work with.

Found 13 audio files.
   Mediu Zhiga.wav
   Ra Bacheeza.wav
   [SP] Alfonso Ortiz Tirado - TE QUIERO DIJISTE.mp3
   [SP] Alvaro Carrillo - Pinotepa Nacional.mp3
   [SP] Lagrimas Negras.mp3

Acoustic Embedding: Idea

For each audio file, we will compute a fixed-length feature vector that summarizes its sound:

  1. Mel-spectrogram statistics

    • Compute a Mel-spectrogram (frequency vs time on a “human” scale).

    • Convert to dB.

    • Take mean and standard deviation across time for each Mel band.
      → This captures overall spectral shape / timbre.

  2. MFCC statistics

    • Compute MFCCs (a compact representation of timbre).

    • Take mean and standard deviation over time for each MFCC coefficient.

  3. Spectral features (each with mean and std over time)

    • Spectral centroid (brightness)

    • Spectral bandwidth

    • Spectral rolloff (e.g., 85% energy)

    • Spectral flatness (tonal vs noise-like)

    • RMS energy (loudness)

    • Zero-crossing rate (noisiness)

All these are concatenated into a single embedding vector per track:

One row per track, one column per feature → ready for clustering.

Acoustic embedding function

One embedding size: 180
First 5 feature names: ['mel_mean_0', 'mel_mean_1', 'mel_mean_2', 'mel_mean_3', 'mel_mean_4']

Compute embeddings for all tracks

Now we will loop over all audio files in the folder and:

  • Compute the acoustic embedding for each track.

  • Store embeddings and basic metadata in a pandas DataFrame.

  • This DataFrame will be our feature matrix for clustering.

Compute embeddings

[1/13] Mediu Zhiga.wav
[2/13] Ra Bacheeza.wav
[3/13] [SP] Alfonso Ortiz Tirado - TE QUIERO DIJISTE.mp3
[4/13] [SP] Alvaro Carrillo - Pinotepa Nacional.mp3
[5/13] [SP] Lagrimas Negras.mp3
[6/13] [SP] Los Panchos - Contigo.mp3
[7/13] [SP] Los Panchos - Jamas Jamas Jamas.mp3
[8/13] [SP] Los Panchos - Te Quiero Dijiste.mp3
[9/13] [SP] Soledad y el Mar - Natalia Lafourcade.mp3
[10/13] [ZAP] Binni Gula_za - Ni_bixi Dxi Zina.mp3
[11/13] [ZAP] Mediu Zhiga.mp3
[12/13] [ZAP] Ra Bacheeza.mp3
[13/13] [ZAP] Sabor a Mi - Trio Galenos Y Mario Carrillo.mp3

Embedding DataFrame shape: (13, 184)
Loading...

Prepare feature matrix for clustering

To cluster tracks, we will:

  1. Extract only the numeric feature columns (embedding dimensions).

  2. Standardize them using z-score scaling (mean 0, std 1) so that:

    • Mel bands, MFCCs, and spectral features are comparable in scale.

  3. Keep file_name and duration_sec for interpreting results later.

Build X and scale

Feature matrix shape (num_tracks, num_features): (13, 180)

k-means clustering

Step 6 — k-means clustering on acoustic embeddings

We first use k-means:

  • You choose the number of clusters k.

  • The algorithm pulls tracks into k groups based on their acoustic embeddings.

  • Each track gets a cluster ID: 0, 1, 2, …, k−1.

k-means assumes clusters are roughly spherical and of similar size.
It is simple and fast, but sometimes misses irregular or uneven clusters.

k-means cluster counts:
cluster_kmeans
0    9
1    4
Name: count, dtype: int64
Loading...

HDBSCAN clustering

Next, we use HDBSCAN (Hierarchical Density-Based Spatial Clustering of Applications with Noise):

  • It can find clusters of different densities and shapes.

  • It does not require choosing k ahead of time.

  • It can label some tracks as noise/outliers with label -1.

We will:

  • Run HDBSCAN on the same standardized feature matrix.

  • Get a cluster label per track (cluster_hdbscan).

HDBSCAN cluster counts (including -1 = noise):
cluster_hdbscan
-1    13
Name: count, dtype: int64
/Users/souvikmandal/AudioVenv/lib/python3.11/site-packages/sklearn/utils/deprecation.py:132: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8.
  warnings.warn(
/Users/souvikmandal/AudioVenv/lib/python3.11/site-packages/sklearn/utils/deprecation.py:132: FutureWarning: 'force_all_finite' was renamed to 'ensure_all_finite' in 1.6 and will be removed in 1.8.
  warnings.warn(
Loading...

Save embeddings and cluster labels

Finally, we will save:

  • A CSV file with:

    • file_name, duration, embedding features, k-means cluster, HDBSCAN cluster.

  • (Optional) You can also save as JSON or pickle if you want to reload easily.

This CSV can then be used in a separate notebook for:

  • visualizations (e.g., 2D scatter plots using PCA/UMAP),

  • checking which songs fall into which cluster,

  • building recommendation or similarity tools.

Saved embeddings + clusters to:
/Users/souvikmandal/Documents/06_Teaching_Mentoring/LS100_comp_etho/2025/media/audio/music_tracks/Audio_Clips/acoustic_embeddings_with_clusters.csv

Visualizing Clusters in 2D with PCA + Plotly - Setup

Our acoustic embeddings live in a high-dimensional space (hundreds of features per track).
To visualize them, we’ll compress them down to 2 dimensions using PCA (Principal Component Analysis):

  • PCA finds directions (components) that capture the most variance in the data.

  • We’ll project each track’s embedding to (PC1, PC2) and make scatter plots.

We’ll then color points by:

  • k-means cluster ID

  • HDBSCAN cluster ID (with -1 = noise/outliers)

This will let us see how clusters are arranged in the acoustic space.

Explained variance by PC1 and PC2: 0.2872734305504054 0.23867184477917308

PCA scatter plot colored by k-means clusters

Each point is one track:

  • Position = projection of its acoustic embedding to the first two principal components (PC1, PC2).

  • Color = k-means cluster ID.

  • Hover text = file name.

This gives a geometric picture of how k-means partitioned the acoustic space.

Below are the color options for the dots in the plot.

px.colors.qualitative.Vivid
px.colors.qualitative.Dark24
px.colors.qualitative.Set1   # very bold, good for small number of clusters
px.colors.qualitative.Set3   # pastel but distinct
px.colors.qualitative.Alphabet  # huge palette

Just replace

color_discrete_sequence=px.colors.qualitative.Bold
Loading...

Visualize HDBSCAN clusters

PCA scatter plot colored by HDBSCAN clusters

Now we color the same PCA projection by HDBSCAN cluster labels:

  • Each color = HDBSCAN cluster ID.

  • Label -1 means “noise” or “unclustered / outlier” points.

This can look quite different from k-means:

  • k-means forces every track into some cluster.

  • HDBSCAN is allowed to say, “these tracks don’t belong to any dense group.”

Loading...

UMAP: Nonlinear 2D Embedding of Acoustic Space

PCA gave us a linear 2D summary of the embeddings.
Now we will use UMAP (Uniform Manifold Approximation and Projection):

  • UMAP is a nonlinear dimensionality reduction method.

  • It tries to preserve local neighborhoods: points that are close in high dimension tend to stay close in the 2D map.

  • This often reveals curved or irregular cluster structure that PCA misses.

We will:

  1. Compute a 2D UMAP projection of our standardized feature matrix X_scaled.

  2. Make two scatter plots (Plotly):

    • one colored by k-means cluster

    • one colored by HDBSCAN cluster

/Users/souvikmandal/AudioVenv/lib/python3.11/site-packages/umap/umap_.py:1952: UserWarning:

n_jobs value 1 overridden to 1 by setting random_state. Use no seed for parallelism.

UMAP embedding shape: (13, 2)

UMAP + k-means visualization

Loading...

UMAP + HDBSCAN visualization

Loading...

Cluster Summaries

To interpret the clusters, we will compute simple summary statistics:

  • Number of tracks in each cluster

  • Average, minimum, and maximum track duration

We will do this for:

  • k-means clusters

  • HDBSCAN clusters (ignoring the noise cluster -1 for summaries)

Summaries for k-means

Numeric metadata columns being summarized (k-means):
['duration_sec', 'sample_rate']
Loading...

summaries for HDBSCAN (ignoring noise)

No non-noise HDBSCAN clusters to summarize.