SmarTrackIA / app.py
Hamsy's picture
Update app.py
a39088f verified
import gradio as gr
import pickle
import numpy as np
import pandas as pd
import os
# --- VÉRIFICATION ET CHARGEMENT ---
MODEL_FILE = "smartrack_health_alert_vet_model.pkl"
ENCODER_FILE = "species_encoder_vet.pkl"
# Fichiers audio par langue (simulés)
# IMPORTANT: Pour une implémentation réelle, ces fichiers MP3 devraient
# contenir l'alerte enregistrée dans la langue spécifiée.
AUDIO_PATHS = {
'Français': {
'alert': "alert_high.mp3", # Français (Alerte Grave)
'ok': "alert_ok.mp3" # Français (Statut OK)
},
'Pular (Peul)': {
'alert': "alert_high_pular.mp3", # Fichier audio Pular (à fournir)
'ok': "alert_ok_pular.mp3" # Fichier audio Pular (à fournir)
},
'Mandinka (Malinké)': {
'alert': "alert_high_mandinka.mp3", # Fichier audio Mandinka (à fournir)
'ok': "alert_ok_mandinka.mp3" # Fichier audio Mandinka (à fournir)
},
'Soussou': {
'alert': "alert_high_soussou.mp3", # Fichier audio Soussou (à fournir)
'ok': "alert_ok_soussou.mp3" # Fichier audio Soussou (à fournir)
}
}
# Messages d'alerte dans différentes langues vernaculaires (texte)
MESSAGES = {
'Français': {
'alert': "🚨 ALERTE: Problème de Santé Détecté. Vérification immédiate recommandée.",
'ok': "✅ Statut de Santé: OK. Les signes vitaux sont dans la plage normale.",
'action': "Veuillez vérifier immédiatement l'animal ou consulter un vétérinaire."
},
'Pular (Peul)': {
'alert': "🚨 **Habbere Sellal Habi !** (Problème de santé grave !)",
'ok': "✅ **Cellal Habi: No Ngol'li.** (Santé OK : Tout est bien.)",
'action': "Jooni jooni ngeesa ndabba oo malla yaara ngesa." # Vérifiez immédiatement...
},
'Mandinka (Malinké)': {
'alert': "🚨 **Nteeri-nkoo Kori!** (Problème de collier !) (Simulation - Le message sera le même)",
'ok': "✅ **Jato Kamma: Ikoo.** (Statut OK : Il n'y a rien.) (Simulation - Le message sera le même)",
'action': "I ye dabba lafii siininiwalla yaara dakteri." # Vous devez vérifier l'animal ou aller chez le docteur.
},
'Soussou': {
'alert': "🚨 **Lanfana Xadi !** (Problème de santé grave !) (Simulation)",
'ok': "✅ **Lanfana: Mu Wali.** (Santé : Tout va bien.) (Simulation)",
'action': "Yandi lanfana xadi, ye dabba la fisa walla ye dakteri xadi." # Vérifiez rapidement l'animal ou allez voir le docteur.
}
}
# Vérification préalable pour s'assurer que les artefacts existent
if not os.path.exists(MODEL_FILE) or not os.path.exists(ENCODER_FILE):
print(f"❌ ERREUR FATALE: Les fichiers du modèle ({MODEL_FILE} ou {ENCODER_FILE}) sont introuvables.")
print("Veuillez vous assurer d'avoir exécuté les étapes de Simulation et d'Entraînement.")
# On laisse le FileNotFoundError, mais on continue avec model=None pour le déploiement local
try:
model = pickle.load(open(MODEL_FILE, "rb"))
encoder = pickle.load(open(ENCODER_FILE, "rb"))
except Exception as e:
print(f"❌ ERREUR: Problème lors du chargement des fichiers pickle : {e}")
model = None
# --- DÉFINITION GLOBALE ---
classes = ['OK (Santé Normale)', 'ALERTE (Intervention Recommandée)']
SPECIES_LIST = list(encoder.categories_[0])
# 2. Fonction de Prédiction avec Output Audio (mis à jour avec Langue)
def predict_health_alert_vocal(langue_choisie, species, hr, spo2, temp, acc_mean, gyro_mean):
""" Prend les données, la langue choisie, et renvoie le texte d'alerte et l'audio correspondant. """
if model is None:
return "Erreur: Modèle non chargé. Veuillez corriger l'erreur ci-dessus.", None
# 1. Préparation des données d'entrée
input_data = pd.DataFrame({
'hr': [hr], 'spo2': [spo2], 'temp': [temp],
'acc_mean': [acc_mean], 'gyro_mean': [gyro_mean],
'species': [species]
})
# 2. Prétraitement
numerical_features = input_data.drop('species', axis=1)
species_encoded = encoder.transform(input_data[['species']])
species_df = pd.DataFrame(species_encoded, columns=encoder.get_feature_names_out(['species']))
X_final = pd.concat([numerical_features, species_df], axis=1)
# 3. Prédiction
prediction = model.predict(X_final)[0]
probas = model.predict_proba(X_final)[0]
predicted_class = classes[prediction]
# Récupération des messages et chemins audio dans la langue choisie
messages = MESSAGES.get(langue_choisie, MESSAGES['Français'])
audio_files = AUDIO_PATHS.get(langue_choisie, AUDIO_PATHS['Français'])
# 4. Formatage des Sorties
if prediction == 1:
# Sélectionne le bon chemin audio pour l'alerte
audio_filename = audio_files['alert']
audio_path = audio_filename if os.path.exists(audio_filename) else None
alert_style = messages['alert']
action_message = messages['action']
else:
# Sélectionne le bon chemin audio pour l'OK
audio_filename = audio_files['ok']
audio_path = audio_filename if os.path.exists(audio_filename) else None
alert_style = messages['ok']
action_message = "" # Pas d'action si OK
# Si le fichier audio n'existe pas, nous utilisons le français par défaut si disponible
if audio_path is None:
if prediction == 1 and os.path.exists(AUDIO_PATHS['Français']['alert']):
audio_path = AUDIO_PATHS['Français']['alert']
elif prediction == 0 and os.path.exists(AUDIO_PATHS['Français']['ok']):
audio_path = AUDIO_PATHS['Français']['ok']
# Construction du rapport textuel final
output_text = f"## {alert_style} \n\n"
output_text += f"**Espèce :** {species.capitalize()}\n"
output_text += f"**Statut Analysé :** **{predicted_class}**\n\n"
output_text += f"--- \n\n"
output_text += f"**Action Recommandée :** {action_message}\n\n"
output_text += f"*(Probabilité d'Alerte : {probas[1]*100:.2f}%)*"
return output_text, audio_path
# 3. Création de l'Interface Gradio (avec le composant Langue en premier)
iface = gr.Interface(
fn=predict_health_alert_vocal,
inputs=[
gr.Dropdown(choices=list(MESSAGES.keys()), label="0. Langue de l'Alerte", value="Français"),
gr.Dropdown(choices=SPECIES_LIST, label="1. Espèce Animale", value="boeuf"),
gr.Slider(minimum=30, maximum=200, value=75, label="2. Rythme Cardiaque (BPM)"),
gr.Slider(minimum=80, maximum=100, value=96, label="3. Saturation O₂ (SpO2 %)"),
gr.Slider(minimum=35.0, maximum=42.0, value=38.0, label="4. Température Corporelle (°C)"),
gr.Slider(minimum=0.0, maximum=5.0, value=0.5, label="5. Mouvement (Accél. Moy.)"),
gr.Slider(minimum=0.0, maximum=5.0, value=1.5, label="6. Mouvement (Gyro. Moy.)"),
],
outputs=[
gr.Markdown(label="Rapport Textuel d'Alerte"),
gr.Audio(label="Alerte Vocale (Si disponible dans la langue choisie)"),
],
title="Système d'Alerte de Santé Vétérinaire SmarTrack (Vocal Multi-Langue)",
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).",
examples=[
['Français', 'boeuf', 55, 96, 38.5, 0.1, 0.1], # Normal
['Pular (Peul)', 'chat', 170, 95, 38.5, 3.0, 3.0], # Normal
['Soussou', 'boeuf', 150, 85, 41.0, 0.0, 0.0], # Alerte en Soussou
]
)
# --- LANCEMENT LOCAL ---
# C'est cette ligne qui fait la différence pour le test local !
iface.launch(share=True)