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.

Dimensionality Reduction Explorer

PCA et UMAP sur les MFCCs. Sélectionner les groupes et la projection.

import os
import json
import numpy as np
import pandas as pd
import plotly.express as px
import ipywidgets as widgets
from IPython.display import display
import IPython.display as ipd
from sklearn.preprocessing import StandardScaler
from sklearn.decomposition import PCA
import warnings
warnings.filterwarnings('ignore')

try:
    import umap
    HAS_UMAP = True
except ImportError:
    HAS_UMAP = False
    print("⚠️ umap non installé — pip install umap-learn")
⚠️ umap non installé — pip install umap-learn
outputs_folder = "../outputs"
data = []
for sound_folder in os.listdir(outputs_folder):
    json_path = os.path.join(outputs_folder, sound_folder, "results.json")
    if os.path.exists(json_path):
        with open(json_path, "r") as f:
            result = json.load(f)
            result["group"] = sound_folder[0]
            data.append(result)

df = pd.DataFrame(data)
audio_dir = os.path.abspath("../data/sounds")
df["audio_path"] = df["file"].apply(lambda x: os.path.join(audio_dir, x))
print(f"✓ {len(df)} sons chargés")
✓ 52 sons chargés
X = np.array(df["mfcc_mean"].tolist())
scaler = StandardScaler()
X_scaled = scaler.fit_transform(X)

pca = PCA(n_components=2)
pca_result = pca.fit_transform(X_scaled)
df["PC1"] = pca_result[:, 0]
df["PC2"] = pca_result[:, 1]
print(f"PCA — variance expliquée : {pca.explained_variance_ratio_.round(3)}")

if HAS_UMAP:
    reducer = umap.UMAP(n_neighbors=10, min_dist=0.3, random_state=42)
    umap_result = reducer.fit_transform(X_scaled)
    df["UMAP1"] = umap_result[:, 0]
    df["UMAP2"] = umap_result[:, 1]
    print("UMAP — calculé")
PCA — variance expliquée : [0.262 0.194]
group_selector = widgets.SelectMultiple(
    options=df["group"].unique(),
    value=tuple(df["group"].unique()),
    description="Group"
)
projection_options = ["PCA", "UMAP"] if HAS_UMAP else ["PCA"]
projection_selector = widgets.ToggleButtons(
    options=projection_options,
    description="Projection"
)

def update_plot(groups, projection):
    filtered_df = df[df["group"].isin(groups)].copy()
    if filtered_df.empty:
        print("Aucune donnée")
        return
    x, y = ("PC1", "PC2") if projection == "PCA" else ("UMAP1", "UMAP2")
    fig = px.scatter(
        filtered_df, x=x, y=y, color="group",
        hover_name="file",
        title=f"{projection} of Crowd Sounds"
    )
    fig.show()

plot_out = widgets.interactive_output(
    update_plot,
    {"groups": group_selector, "projection": projection_selector}
)
display(group_selector, projection_selector, plot_out)
Loading...
Loading...
Loading...