NIIHAAD commited on
Commit
1ce42f2
·
1 Parent(s): 3406525

predict with metadata : preparation of data

Browse files
Files changed (1) hide show
  1. app.py +144 -7
app.py CHANGED
@@ -1,17 +1,154 @@
1
  import gradio as gr
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2
 
3
  # -------- Fonctions (logique plus tard) --------
4
 
5
  def predict_with_metadata(url):
6
  if url.strip() == "":
7
  return "❌ Veuillez entrer une URL FreeSound."
8
-
9
- # PLUS TARD :
10
- # - extraire ID
11
- # - appeler API FreeSound
12
- # - calculer score
13
-
14
- return "🔍 Résultat (métadonnées) : SON POPULAIRE (exemple)"
 
 
 
 
 
 
 
 
 
15
 
16
  def predict_with_audio(url):
17
  if url.strip() == "":
 
1
  import gradio as gr
2
+ import os
3
+ import pandas as pd
4
+ import numpy as np
5
+ from sklearn.preprocessing import KBinsDiscretizer, StandardScaler, OneHotEncoder
6
+ import freesound
7
+ import gensim.downloader as api
8
+
9
+
10
+ # Token FreeSound
11
+ client = freesound.FreesoundClient()
12
+ client.set_token("zE9NjEOgUMzH9K7mjiGBaPJiNwJLjSM53LevarRK")
13
+
14
+ # Répertoire dataset
15
+ dataset_dir = "dataset_audio"
16
+ os.makedirs(dataset_dir, exist_ok=True)
17
+
18
+ # Liste des métadonnées importantes
19
+ metadata_cols = ["name", "num_ratings", "tags", "username",
20
+ "description", "created", "license", "num_downloads", "channels",
21
+ "filesize", "category_is_user_provided", "duration", "avg_rating",
22
+ "category", "subcategory", "type", "samplerate"
23
+ ]
24
+
25
+ def fetch_sound_metadata(sound_url):
26
+ # Extraire l'ID FreeSound de l'URL
27
+ sound_id = int(sound_url.rstrip("/").split("/")[-1])
28
+ sound = client.get_sound(sound_id)
29
+
30
+ file_name = f"{sound.name.replace(' ', '_')}.mp3"
31
+ file_path = os.path.join(dataset_dir, file_name)
32
+
33
+ # Télécharger le preview
34
+ try:
35
+ sound.retrieve_preview(dataset_dir, file_name)
36
+ except Exception as e:
37
+ print(f"Erreur téléchargement {file_name} : {e}")
38
+ file_path = None
39
+
40
+ data = {
41
+ "file_path": file_path,
42
+ "name": sound.name,
43
+ "num_ratings": sound.num_ratings,
44
+ "tags": ",".join(sound.tags) if hasattr(sound, "tags") else "",
45
+ "username": sound.username,
46
+ "description": sound.description if sound.description else "",
47
+ "created": getattr(sound, "created", ""),
48
+ "license": getattr(sound, "license", ""),
49
+ "num_downloads": getattr(sound, "num_downloads", 0),
50
+ "channels": getattr(sound, "channels", 0),
51
+ "filesize": getattr(sound, "filesize", 0),
52
+ "category_is_user_provided": getattr(sound, "category_is_user_provided", 0),
53
+ "duration": getattr(sound, "duration", 0),
54
+ "avg_rating": getattr(sound, "avg_rating", 0),
55
+ "category": getattr(sound, "category", "Unknown"),
56
+ "subcategory": getattr(sound, "subcategory", "Other"),
57
+ "type": getattr(sound, "type", ""),
58
+ "samplerate": getattr(sound, "samplerate", 0)
59
+ }
60
+ return pd.DataFrame([data])
61
+
62
+
63
+ def preprocess_targets(df):
64
+ # num_downloads -> discretisation 3 classes
65
+ X = df["num_downloads"].to_numpy().reshape(-1,1)
66
+ est = KBinsDiscretizer(n_bins=3, encode="ordinal", strategy="quantile")
67
+ df["num_downloads_class"] = est.fit_transform(X).astype(int)
68
+
69
+ # avg_rating -> discretisation en 4 classes
70
+ mask_non_zero = df["avg_rating"] != 0
71
+ X_non_zero = df.loc[mask_non_zero, "avg_rating"].to_numpy().reshape(-1,1)
72
+ est = KBinsDiscretizer(n_bins=3, encode="ordinal", strategy="quantile")
73
+ df["avg_rating_class"] = 0
74
+ df.loc[mask_non_zero, "avg_rating_class"] = est.fit_transform(X_non_zero).flatten().astype(int) + 1
75
+ df["avg_rating"] = df["avg_rating_class"]
76
+ df.drop(columns=["avg_rating_class"], inplace=True)
77
+
78
+ return df
79
+
80
+ def preprocess_features(df):
81
+ df = df.copy()
82
+
83
+ # Colonnes booléennes
84
+ df["category_is_user_provided"] = df["category_is_user_provided"].astype(int)
85
+
86
+ # Colonnes catégorielles -> one-hot
87
+ cat_cols = ["license", "category", "type"]
88
+ df[cat_cols] = df[cat_cols].fillna("Unknown")
89
+ df = pd.get_dummies(df, columns=cat_cols, drop_first=False)
90
+
91
+ # username -> frequency encoding
92
+ user_freq = df["username"].value_counts(normalize=True)
93
+ df["username_freq"] = df["username"].map(user_freq)
94
+ df.drop(columns=["username"], inplace=True)
95
+
96
+ # subcategory -> one-hot, rare <2% regroupé
97
+ df["subcategory"] = df["subcategory"].fillna("Other")
98
+ counts = df["subcategory"].value_counts(normalize=True)*100
99
+ rare_subs = counts[counts<2].index
100
+ df["subcategory"] = df["subcategory"].apply(lambda x: "Other" if x in rare_subs else x)
101
+ ohe = OneHotEncoder(sparse_output=False)
102
+ subcat_ohe = ohe.fit_transform(df[["subcategory"]])
103
+ subcat_df = pd.DataFrame(subcat_ohe, columns=[f"subcategory_{c}" for c in ohe.categories_[0]], index=df.index)
104
+ df = pd.concat([df, subcat_df], axis=1)
105
+ df.drop(columns=["subcategory"], inplace=True)
106
+
107
+ # Colonnes numériques -> log1p + standard scaler
108
+ numeric_cols = ["num_ratings", "filesize", "duration", "samplerate"]
109
+ for col in numeric_cols:
110
+ df[col] = np.log1p(df[col])
111
+ scaler = StandardScaler()
112
+ df[numeric_cols] = scaler.fit_transform(df[numeric_cols])
113
+
114
+ # Description -> vecteur GloVe 100 dim
115
+ glove_model = api.load("glove-wiki-gigaword-100")
116
+ def description_to_vec(text, model):
117
+ if not text: return np.zeros(100)
118
+ words = text.lower().split()
119
+ vecs = [model[w] for w in words if w in model]
120
+ return np.mean(vecs, axis=0) if vecs else np.zeros(100)
121
+ desc_vecs = np.vstack(df['description'].fillna('').apply(lambda x: description_to_vec(x, glove_model)))
122
+ desc_cols = [f'description_glove_{i}' for i in range(desc_vecs.shape[1])]
123
+ df[desc_cols] = pd.DataFrame(desc_vecs, columns=desc_cols, index=df.index)
124
+ df.drop(columns=["description"], inplace=True)
125
+
126
+ return df
127
+
128
+
129
+
130
 
131
  # -------- Fonctions (logique plus tard) --------
132
 
133
  def predict_with_metadata(url):
134
  if url.strip() == "":
135
  return "❌ Veuillez entrer une URL FreeSound."
136
+
137
+ try:
138
+ # Récupérer les métadonnées
139
+ df = fetch_sound_metadata(url)
140
+
141
+ # Prétraiter les targets et features si besoin
142
+ df = preprocess_targets(df)
143
+ df = preprocess_features(df)
144
+
145
+ # Afficher un résumé clair des métadonnées extraites
146
+ info = df.T # transpose pour afficher colonne -> valeur
147
+ info_str = "\n".join([f"{idx}: {val[0]}" for idx, val in info.iterrows()])
148
+ return f"✅ Métadonnées extraites :\n\n{info_str}"
149
+
150
+ except Exception as e:
151
+ return f"❌ Erreur lors de l'extraction : {e}"
152
 
153
  def predict_with_audio(url):
154
  if url.strip() == "":