Hamsy commited on
Commit
ec25577
·
verified ·
1 Parent(s): 6c907e0

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +102 -26
app.py CHANGED
@@ -4,59 +4,128 @@ import numpy as np
4
  import pandas as pd
5
  import os
6
 
7
- # 1. Chargement des Artefacts
8
  MODEL_FILE = "smartrack_health_alert_vet_model.pkl"
9
  ENCODER_FILE = "species_encoder_vet.pkl"
10
 
11
- # Assurez-vous que ces fichiers audio ont été générés en amont
12
- ALERT_AUDIO = "alert_high.mp3"
13
- OK_AUDIO = "alert_ok.mp3"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
14
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
15
  try:
16
  model = pickle.load(open(MODEL_FILE, "rb"))
17
  encoder = pickle.load(open(ENCODER_FILE, "rb"))
18
  except Exception as e:
19
- # Cas d'erreur pour le déploiement
20
- print(f"Erreur de chargement des artefacts : {e}")
21
  model = None
22
 
 
23
  classes = ['OK (Santé Normale)', 'ALERTE (Intervention Recommandée)']
24
  SPECIES_LIST = list(encoder.categories_[0])
25
 
26
 
27
- # 2. Fonction de Prédiction avec Output Audio
28
- def predict_health_alert_vocal(species, hr, spo2, temp, acc_mean, gyro_mean):
29
- """ Prend les données et renvoie le texte d'alerte ET le fichier audio correspondant. """
30
 
31
  if model is None:
32
- return "Erreur: Modèle non chargé.", None # Retourne le texte et l'audio (None)
33
 
 
34
  input_data = pd.DataFrame({
35
  'hr': [hr], 'spo2': [spo2], 'temp': [temp],
36
  'acc_mean': [acc_mean], 'gyro_mean': [gyro_mean],
37
  'species': [species]
38
  })
39
 
 
40
  numerical_features = input_data.drop('species', axis=1)
41
  species_encoded = encoder.transform(input_data[['species']])
42
  species_df = pd.DataFrame(species_encoded, columns=encoder.get_feature_names_out(['species']))
43
 
44
  X_final = pd.concat([numerical_features, species_df], axis=1)
45
 
 
46
  prediction = model.predict(X_final)[0]
47
  probas = model.predict_proba(X_final)[0]
48
  predicted_class = classes[prediction]
49
 
50
- # Choix du fichier audio et du message
 
 
 
 
51
  if prediction == 1:
52
- audio_path = ALERT_AUDIO
53
- alert_style = "🚨 **ALERTE: Problème de Santé Détecté** 🚨"
54
- action_message = "Veuillez vérifier immédiatement l'animal ou consulter un vétérinaire. Écoutez l'alerte vocale ci-dessous."
 
 
 
55
  else:
56
- audio_path = OK_AUDIO
57
- alert_style = "✅ **Statut de Santé: OK**"
58
- action_message = "Les signes vitaux sont dans la plage normale pour l'espèce. Écoutez le message de confirmation ci-dessous."
 
 
 
59
 
 
 
 
 
 
 
 
 
60
  output_text = f"## {alert_style} \n\n"
61
  output_text += f"**Espèce :** {species.capitalize()}\n"
62
  output_text += f"**Statut Analysé :** **{predicted_class}**\n\n"
@@ -64,13 +133,14 @@ def predict_health_alert_vocal(species, hr, spo2, temp, acc_mean, gyro_mean):
64
  output_text += f"**Action Recommandée :** {action_message}\n\n"
65
  output_text += f"*(Probabilité d'Alerte : {probas[1]*100:.2f}%)*"
66
 
67
- return output_text, audio_path # Retourne le texte ET le chemin du fichier audio
68
 
69
 
70
- # 3. Création de l'Interface Gradio (avec le composant Audio)
71
  iface = gr.Interface(
72
- fn=predict_health_alert_vocal, # Nouvelle fonction
73
  inputs=[
 
74
  gr.Dropdown(choices=SPECIES_LIST, label="1. Espèce Animale", value="boeuf"),
75
  gr.Slider(minimum=30, maximum=200, value=75, label="2. Rythme Cardiaque (BPM)"),
76
  gr.Slider(minimum=80, maximum=100, value=96, label="3. Saturation O₂ (SpO2 %)"),
@@ -79,12 +149,18 @@ iface = gr.Interface(
79
  gr.Slider(minimum=0.0, maximum=5.0, value=1.5, label="6. Mouvement (Gyro. Moy.)"),
80
  ],
81
  outputs=[
82
- gr.Markdown(label="Rapport Textuel d'Alerte"), # Premier output: Texte
83
- gr.Audio(label="Alerte Vocale (Cliquez pour Écouter)"), # Deuxième output: Audio
84
  ],
85
- title="Système d'Alerte de Santé Vétérinaire SmarTrack (Vocal)",
86
- description="Le modèle prédit l'état de santé et génère une alerte vocale immédiate pour le propriétaire.",
 
 
 
 
 
87
  )
88
 
89
- # if __name__ == "__main__":
90
- # iface.launch()
 
 
4
  import pandas as pd
5
  import os
6
 
7
+ # --- VÉRIFICATION ET CHARGEMENT ---
8
  MODEL_FILE = "smartrack_health_alert_vet_model.pkl"
9
  ENCODER_FILE = "species_encoder_vet.pkl"
10
 
11
+ # Fichiers audio par langue (simulés)
12
+ # IMPORTANT: Pour une implémentation réelle, ces fichiers MP3 devraient
13
+ # contenir l'alerte enregistrée dans la langue spécifiée.
14
+ AUDIO_PATHS = {
15
+ 'Français': {
16
+ 'alert': "alert_high.mp3", # Français (Alerte Grave)
17
+ 'ok': "alert_ok.mp3" # Français (Statut OK)
18
+ },
19
+ 'Pular (Peul)': {
20
+ 'alert': "alert_high_pular.mp3", # Fichier audio Pular (à fournir)
21
+ 'ok': "alert_ok_pular.mp3" # Fichier audio Pular (à fournir)
22
+ },
23
+ 'Mandinka (Malinké)': {
24
+ 'alert': "alert_high_mandinka.mp3", # Fichier audio Mandinka (à fournir)
25
+ 'ok': "alert_ok_mandinka.mp3" # Fichier audio Mandinka (à fournir)
26
+ },
27
+ 'Soussou': {
28
+ 'alert': "alert_high_soussou.mp3", # Fichier audio Soussou (à fournir)
29
+ 'ok': "alert_ok_soussou.mp3" # Fichier audio Soussou (à fournir)
30
+ }
31
+ }
32
 
33
+ # Messages d'alerte dans différentes langues vernaculaires (texte)
34
+ MESSAGES = {
35
+ 'Français': {
36
+ 'alert': "🚨 ALERTE: Problème de Santé Détecté. Vérification immédiate recommandée.",
37
+ 'ok': "✅ Statut de Santé: OK. Les signes vitaux sont dans la plage normale.",
38
+ 'action': "Veuillez vérifier immédiatement l'animal ou consulter un vétérinaire."
39
+ },
40
+ 'Pular (Peul)': {
41
+ 'alert': "🚨 **Habbere Sellal Habi !** (Problème de santé grave !)",
42
+ 'ok': "✅ **Cellal Habi: No Ngol'li.** (Santé OK : Tout est bien.)",
43
+ 'action': "Jooni jooni ngeesa ndabba oo malla yaara ngesa." # Vérifiez immédiatement...
44
+ },
45
+ 'Mandinka (Malinké)': {
46
+ 'alert': "🚨 **Nteeri-nkoo Kori!** (Problème de collier !) (Simulation - Le message sera le même)",
47
+ 'ok': "✅ **Jato Kamma: Ikoo.** (Statut OK : Il n'y a rien.) (Simulation - Le message sera le même)",
48
+ 'action': "I ye dabba lafii siininiwalla yaara dakteri." # Vous devez vérifier l'animal ou aller chez le docteur.
49
+ },
50
+ 'Soussou': {
51
+ 'alert': "🚨 **Lanfana Xadi !** (Problème de santé grave !) (Simulation)",
52
+ 'ok': "✅ **Lanfana: Mu Wali.** (Santé : Tout va bien.) (Simulation)",
53
+ 'action': "Yandi lanfana xadi, ye dabba la fisa walla ye dakteri xadi." # Vérifiez rapidement l'animal ou allez voir le docteur.
54
+ }
55
+ }
56
+
57
+ # Vérification préalable pour s'assurer que les artefacts existent
58
+ if not os.path.exists(MODEL_FILE) or not os.path.exists(ENCODER_FILE):
59
+ print(f"❌ ERREUR FATALE: Les fichiers du modèle ({MODEL_FILE} ou {ENCODER_FILE}) sont introuvables.")
60
+ print("Veuillez vous assurer d'avoir exécuté les étapes de Simulation et d'Entraînement.")
61
+ # On laisse le FileNotFoundError, mais on continue avec model=None pour le déploiement local
62
+
63
  try:
64
  model = pickle.load(open(MODEL_FILE, "rb"))
65
  encoder = pickle.load(open(ENCODER_FILE, "rb"))
66
  except Exception as e:
67
+ print(f"❌ ERREUR: Problème lors du chargement des fichiers pickle : {e}")
 
68
  model = None
69
 
70
+ # --- DÉFINITION GLOBALE ---
71
  classes = ['OK (Santé Normale)', 'ALERTE (Intervention Recommandée)']
72
  SPECIES_LIST = list(encoder.categories_[0])
73
 
74
 
75
+ # 2. Fonction de Prédiction avec Output Audio (mis à jour avec Langue)
76
+ def predict_health_alert_vocal(langue_choisie, species, hr, spo2, temp, acc_mean, gyro_mean):
77
+ """ Prend les données, la langue choisie, et renvoie le texte d'alerte et l'audio correspondant. """
78
 
79
  if model is None:
80
+ return "Erreur: Modèle non chargé. Veuillez corriger l'erreur ci-dessus.", None
81
 
82
+ # 1. Préparation des données d'entrée
83
  input_data = pd.DataFrame({
84
  'hr': [hr], 'spo2': [spo2], 'temp': [temp],
85
  'acc_mean': [acc_mean], 'gyro_mean': [gyro_mean],
86
  'species': [species]
87
  })
88
 
89
+ # 2. Prétraitement
90
  numerical_features = input_data.drop('species', axis=1)
91
  species_encoded = encoder.transform(input_data[['species']])
92
  species_df = pd.DataFrame(species_encoded, columns=encoder.get_feature_names_out(['species']))
93
 
94
  X_final = pd.concat([numerical_features, species_df], axis=1)
95
 
96
+ # 3. Prédiction
97
  prediction = model.predict(X_final)[0]
98
  probas = model.predict_proba(X_final)[0]
99
  predicted_class = classes[prediction]
100
 
101
+ # Récupération des messages et chemins audio dans la langue choisie
102
+ messages = MESSAGES.get(langue_choisie, MESSAGES['Français'])
103
+ audio_files = AUDIO_PATHS.get(langue_choisie, AUDIO_PATHS['Français'])
104
+
105
+ # 4. Formatage des Sorties
106
  if prediction == 1:
107
+ # Sélectionne le bon chemin audio pour l'alerte
108
+ audio_filename = audio_files['alert']
109
+ audio_path = audio_filename if os.path.exists(audio_filename) else None
110
+
111
+ alert_style = messages['alert']
112
+ action_message = messages['action']
113
  else:
114
+ # Sélectionne le bon chemin audio pour l'OK
115
+ audio_filename = audio_files['ok']
116
+ audio_path = audio_filename if os.path.exists(audio_filename) else None
117
+
118
+ alert_style = messages['ok']
119
+ action_message = "" # Pas d'action si OK
120
 
121
+ # Si le fichier audio n'existe pas, nous utilisons le français par défaut si disponible
122
+ if audio_path is None:
123
+ if prediction == 1 and os.path.exists(AUDIO_PATHS['Français']['alert']):
124
+ audio_path = AUDIO_PATHS['Français']['alert']
125
+ elif prediction == 0 and os.path.exists(AUDIO_PATHS['Français']['ok']):
126
+ audio_path = AUDIO_PATHS['Français']['ok']
127
+
128
+ # Construction du rapport textuel final
129
  output_text = f"## {alert_style} \n\n"
130
  output_text += f"**Espèce :** {species.capitalize()}\n"
131
  output_text += f"**Statut Analysé :** **{predicted_class}**\n\n"
 
133
  output_text += f"**Action Recommandée :** {action_message}\n\n"
134
  output_text += f"*(Probabilité d'Alerte : {probas[1]*100:.2f}%)*"
135
 
136
+ return output_text, audio_path
137
 
138
 
139
+ # 3. Création de l'Interface Gradio (avec le composant Langue en premier)
140
  iface = gr.Interface(
141
+ fn=predict_health_alert_vocal,
142
  inputs=[
143
+ gr.Dropdown(choices=list(MESSAGES.keys()), label="0. Langue de l'Alerte", value="Français"),
144
  gr.Dropdown(choices=SPECIES_LIST, label="1. Espèce Animale", value="boeuf"),
145
  gr.Slider(minimum=30, maximum=200, value=75, label="2. Rythme Cardiaque (BPM)"),
146
  gr.Slider(minimum=80, maximum=100, value=96, label="3. Saturation O₂ (SpO2 %)"),
 
149
  gr.Slider(minimum=0.0, maximum=5.0, value=1.5, label="6. Mouvement (Gyro. Moy.)"),
150
  ],
151
  outputs=[
152
+ gr.Markdown(label="Rapport Textuel d'Alerte"),
153
+ gr.Audio(label="Alerte Vocale (Si disponible dans la langue choisie)"),
154
  ],
155
+ title="Système d'Alerte de Santé Vétérinaire SmarTrack (Vocal Multi-Langue)",
156
+ description="Validation locale : Le modèle prédit l'état de santé et affiche les alertes dans la langue choisie (le fichier audio est sélectionné en conséquence).",
157
+ examples=[
158
+ ['Français', 'boeuf', 55, 96, 38.5, 0.1, 0.1], # Normal
159
+ ['Pular (Peul)', 'chat', 170, 95, 38.5, 3.0, 3.0], # Normal
160
+ ['Soussou', 'boeuf', 150, 85, 41.0, 0.0, 0.0], # Alerte en Soussou
161
+ ]
162
  )
163
 
164
+ # --- LANCEMENT LOCAL ---
165
+ # C'est cette ligne qui fait la différence pour le test local !
166
+ iface.launch(share=True)