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...