QnxprU69yCNg8XJ commited on
Commit
52a62d1
·
1 Parent(s): bf15010

Replace with demo classifier that generates realistic random scores (Low/Moderate/High)

Browse files
create_demo_classifier.py ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Créer un classifier de DEMO qui génère des scores variables et réalistes
4
+ ATTENTION: POUR TESTS UNIQUEMENT - PAS POUR PRODUCTION
5
+ """
6
+ import numpy as np
7
+ import joblib
8
+ from sklearn.base import BaseEstimator, ClassifierMixin
9
+
10
+ class RandomRealisticClassifier(BaseEstimator, ClassifierMixin):
11
+ """
12
+ Classifier qui génère des scores aléatoires mais réalistes
13
+ - Low: 0.0 - 0.4 (40% des cas)
14
+ - Moderate: 0.4 - 0.7 (35% des cas)
15
+ - High: 0.7 - 1.0 (25% des cas)
16
+ """
17
+ def __init__(self, random_state=None):
18
+ self.random_state = random_state
19
+ self.classes_ = np.array([0, 1])
20
+
21
+ def fit(self, X, y):
22
+ """Fake fit - ne fait rien"""
23
+ return self
24
+
25
+ def predict(self, X):
26
+ """Génère des prédictions basées sur les probabilités"""
27
+ probas = self.predict_proba(X)
28
+ return (probas[:, 1] > 0.5).astype(int)
29
+
30
+ def predict_proba(self, X):
31
+ """
32
+ Génère des probabilités aléatoires réalistes
33
+ """
34
+ n_samples = X.shape[0]
35
+ rng = np.random.RandomState(self.random_state)
36
+
37
+ # Générer des scores pour chaque sample
38
+ scores = []
39
+ for i in range(n_samples):
40
+ # Utiliser les features pour créer une "seed" unique par sample
41
+ seed = int(np.abs(np.sum(X[i]) * 1000)) % 1000000
42
+ sample_rng = np.random.RandomState(seed)
43
+
44
+ # Choisir une catégorie aléatoirement
45
+ category = sample_rng.choice(['low', 'moderate', 'high'],
46
+ p=[0.40, 0.35, 0.25])
47
+
48
+ if category == 'low':
49
+ # Low: 0.05 - 0.40
50
+ score = sample_rng.uniform(0.05, 0.40)
51
+ elif category == 'moderate':
52
+ # Moderate: 0.40 - 0.70
53
+ score = sample_rng.uniform(0.40, 0.70)
54
+ else: # high
55
+ # High: 0.70 - 0.95
56
+ score = sample_rng.uniform(0.70, 0.95)
57
+
58
+ scores.append(score)
59
+
60
+ scores = np.array(scores)
61
+ # Retourner les probabilités pour [classe 0, classe 1]
62
+ probas = np.column_stack([1 - scores, scores])
63
+ return probas
64
+
65
+ # Créer et sauvegarder le classifier
66
+ clf = RandomRealisticClassifier(random_state=42)
67
+
68
+ # Fake fit avec des données synthétiques (nécessaire pour scikit-learn)
69
+ X_dummy = np.random.randn(10, 512)
70
+ y_dummy = np.array([0, 1, 0, 1, 0, 1, 0, 1, 0, 1])
71
+ clf.fit(X_dummy, y_dummy)
72
+
73
+ # Sauvegarder
74
+ joblib.dump(clf, "pneumonia_classifier_demo.joblib")
75
+
76
+ print("✅ Classifier de DEMO créé: pneumonia_classifier_demo.joblib")
77
+ print("\n📊 Distribution des scores générés:")
78
+ print(" - Low (0.0-0.4): 40% des cas")
79
+ print(" - Moderate (0.4-0.7): 35% des cas")
80
+ print(" - High (0.7-1.0): 25% des cas")
81
+ print("\n⚠️ Ce modèle génère des scores ALÉATOIRES pour tester l'interface")
82
+ print(" Chaque fichier audio donnera un score différent (mais cohérent)")
83
+ print(" Pour la production, utilisez retrain_with_openl3.py avec vos vraies données")
84
+
85
+ # Test du modèle
86
+ print("\n🧪 Test du classifier:")
87
+ X_test = np.random.randn(10, 512)
88
+ for i in range(10):
89
+ proba = clf.predict_proba(X_test[i:i+1])[0, 1]
90
+ level = "Low" if proba < 0.4 else "Moderate" if proba < 0.7 else "High"
91
+ print(f" Sample {i+1}: {proba:.4f} ({level})")
pneumonia_classifier.joblib CHANGED
Binary files a/pneumonia_classifier.joblib and b/pneumonia_classifier.joblib differ
 
retrain_with_openl3.py ADDED
@@ -0,0 +1,118 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ #!/usr/bin/env python3
2
+ """
3
+ Script pour réentraîner le classifier avec les embeddings OpenL3
4
+ """
5
+ import numpy as np
6
+ import joblib
7
+ from sklearn.linear_model import LogisticRegression
8
+ from sklearn.ensemble import RandomForestClassifier
9
+ from sklearn.model_selection import train_test_split
10
+ from sklearn.metrics import classification_report, accuracy_score
11
+ from inference_service import preprocess_audio, generate_embeddings
12
+
13
+ def train_classifier_with_openl3():
14
+ """
15
+ Entraîner un nouveau classifier avec vos données audio + OpenL3
16
+ """
17
+ print("=" * 60)
18
+ print("RÉENTRAÎNEMENT DU CLASSIFIER AVEC OPENL3")
19
+ print("=" * 60)
20
+
21
+ # TODO: Remplacez ceci par vos vrais chemins de données
22
+ # Format attendu:
23
+ # - audio_files_pneumonia: liste de chemins vers fichiers audio de pneumonie
24
+ # - audio_files_normal: liste de chemins vers fichiers audio normaux
25
+
26
+ audio_files_pneumonia = [
27
+ # "path/to/pneumonia_sample1.wav",
28
+ # "path/to/pneumonia_sample2.wav",
29
+ # ...
30
+ ]
31
+
32
+ audio_files_normal = [
33
+ # "path/to/normal_sample1.wav",
34
+ # "path/to/normal_sample2.wav",
35
+ # ...
36
+ ]
37
+
38
+ if not audio_files_pneumonia or not audio_files_normal:
39
+ print("❌ ERREUR: Vous devez fournir vos fichiers audio d'entraînement")
40
+ print("Éditez ce script et ajoutez les chemins dans audio_files_pneumonia et audio_files_normal")
41
+ return
42
+
43
+ print(f"Fichiers pneumonie: {len(audio_files_pneumonia)}")
44
+ print(f"Fichiers normaux: {len(audio_files_normal)}")
45
+
46
+ # Générer les embeddings
47
+ X = []
48
+ y = []
49
+
50
+ print("\n🔄 Génération des embeddings pour pneumonie...")
51
+ for audio_file in audio_files_pneumonia:
52
+ clips = preprocess_audio(audio_file)
53
+ if len(clips) > 0:
54
+ embeddings = generate_embeddings(clips)
55
+ # Moyenne des embeddings de tous les clips
56
+ X.append(np.mean(embeddings, axis=0))
57
+ y.append(1) # Pneumonie
58
+
59
+ print("🔄 Génération des embeddings pour fichiers normaux...")
60
+ for audio_file in audio_files_normal:
61
+ clips = preprocess_audio(audio_file)
62
+ if len(clips) > 0:
63
+ embeddings = generate_embeddings(clips)
64
+ X.append(np.mean(embeddings, axis=0))
65
+ y.append(0) # Normal
66
+
67
+ X = np.array(X)
68
+ y = np.array(y)
69
+
70
+ print(f"\n✅ Dataset créé: {X.shape[0]} samples, {X.shape[1]} features")
71
+ print(f" Pneumonie: {np.sum(y == 1)}, Normal: {np.sum(y == 0)}")
72
+
73
+ # Split train/test
74
+ X_train, X_test, y_train, y_test = train_test_split(
75
+ X, y, test_size=0.2, random_state=42, stratify=y
76
+ )
77
+
78
+ print(f"\n📊 Train: {len(X_train)} samples")
79
+ print(f"📊 Test: {len(X_test)} samples")
80
+
81
+ # Entraîner plusieurs modèles
82
+ models = {
83
+ "LogisticRegression": LogisticRegression(max_iter=1000, random_state=42),
84
+ "RandomForest": RandomForestClassifier(n_estimators=100, random_state=42),
85
+ }
86
+
87
+ best_model = None
88
+ best_score = 0
89
+ best_name = ""
90
+
91
+ for name, model in models.items():
92
+ print(f"\n🤖 Entraînement: {name}")
93
+ model.fit(X_train, y_train)
94
+
95
+ y_pred = model.predict(X_test)
96
+ accuracy = accuracy_score(y_test, y_pred)
97
+
98
+ print(f" Accuracy: {accuracy:.4f}")
99
+ print(classification_report(y_test, y_pred,
100
+ target_names=['Normal', 'Pneumonia']))
101
+
102
+ if accuracy > best_score:
103
+ best_score = accuracy
104
+ best_model = model
105
+ best_name = name
106
+
107
+ print(f"\n🏆 Meilleur modèle: {best_name} (Accuracy: {best_score:.4f})")
108
+
109
+ # Sauvegarder
110
+ output_path = "pneumonia_classifier_openl3.joblib"
111
+ joblib.dump(best_model, output_path)
112
+ print(f"✅ Modèle sauvegardé: {output_path}")
113
+
114
+ print("\n⚠️ IMPORTANT: Renommez ce fichier en 'pneumonia_classifier.joblib'")
115
+ print(" ou mettez à jour app.py pour utiliser 'pneumonia_classifier_openl3.joblib'")
116
+
117
+ if __name__ == "__main__":
118
+ train_classifier_with_openl3()