# app.py : Application Streamlit avec Modèle Classique et ANN import streamlit as st import pandas as pd import numpy as np import joblib import matplotlib.pyplot as plt from tensorflow.keras.models import load_model st.set_page_config(page_title="App Cardiaque", layout="centered") # Chargement des modèles et scalers model = joblib.load("meilleur_modele.pkl") scaler = joblib.load("scaler.pkl") ann_model = load_model("ann_model.h5") ann_scaler = joblib.load("ann_model_scaler.pkl")['scaler'] def home(): st.title("🫀 Application de Prédiction Cardiaque") st.markdown( """ Cette application prédit le **risque de décès** chez les patients atteints d'insuffisance cardiaque à partir de données cliniques. **Fonctionnalités :** - Prédiction individuelle (modèle classique) - Prédiction avec modèle ANN (réseau de neurones) - Chargement de fichiers CSV pour des prédictions multiples - Historique de session - Visualisation des probabilités et importance des variables """ ) def collect_input(): age = st.slider("Âge", 18, 100, 50) anaemia = st.selectbox("Anémie", [0, 1], format_func=lambda x: "Oui" if x else "Non") creatinine_phosphokinase = st.number_input("Créatinine phosphokinase", 10, 10000, 200) diabetes = st.selectbox("Diabète", [0, 1], format_func=lambda x: "Oui" if x else "Non") ejection_fraction = st.slider("Fraction d'éjection (%)", 10, 80, 35) high_blood_pressure = st.selectbox("Hypertension", [0, 1], format_func=lambda x: "Oui" if x else "Non") platelets = st.number_input("Plaquettes (en µL)", 25000.0, 850000.0, 300000.0) serum_creatinine = st.number_input("Créatinine sérique", 0.1, 10.0, 1.0) serum_sodium = st.slider("Sodium sérique", 110, 150, 135) sex = st.selectbox("Sexe", [0, 1], format_func=lambda x: "Homme" if x else "Femme") smoking = st.selectbox("Fumeur", [0, 1], format_func=lambda x: "Oui" if x else "Non") time = st.slider("Temps depuis admission (jours)", 0, 300, 100) return pd.DataFrame([{ 'age': age, 'anaemia': anaemia, 'creatinine_phosphokinase': creatinine_phosphokinase, 'diabetes': diabetes, 'ejection_fraction': ejection_fraction, 'high_blood_pressure': high_blood_pressure, 'platelets': platelets, 'serum_creatinine': serum_creatinine, 'serum_sodium': serum_sodium, 'sex': sex, 'smoking': smoking, 'time': time }]) def prediction_page(): st.title("🔍 Prédiction Individuelle (Modèle Classique)") input_df = collect_input() st.write("### Données entrées :", input_df) if st.button("Prédire avec modèle classique"): X_scaled = scaler.transform(input_df) prediction = model.predict(X_scaled)[0] proba = model.predict_proba(X_scaled)[0] st.markdown(f"**Probabilité de décès :** {proba[1]*100:.2f}%") st.markdown(f"**Probabilité de survie :** {proba[0]*100:.2f}%") fig, ax = plt.subplots() ax.bar(["Survie", "Décès"], proba, color=["green", "red"]) st.pyplot(fig) if prediction == 1: st.error("⚠️ Risque élevé de décès détecté.") else: st.success("✅ Le patient a de bonnes chances de survie.") if "history" not in st.session_state: st.session_state["history"] = [] st.session_state["history"].append({ "Survie (%)": round(proba[0]*100, 2), "Décès (%)": round(proba[1]*100, 2), "Décès prédit": "Oui" if prediction == 1 else "Non" }) def ann_prediction_page(): st.title("🤖 Prédiction avec Réseau de Neurones (ANN)") input_df = collect_input() st.write("### Données entrées :", input_df) if st.button("Prédire avec modèle ANN"): X_ann_scaled = ann_scaler.transform(input_df) ann_pred = ann_model.predict(X_ann_scaled)[0][0] st.metric("Probabilité de décès (ANN)", f"{ann_pred*100:.2f}%") fig, ax = plt.subplots() ax.bar(["Survie", "Décès"], [1-ann_pred, ann_pred], color=["green", "red"]) st.pyplot(fig) if ann_pred >= 0.5: st.error("⚠️ Risque élevé détecté (ANN)") else: st.success("✅ Faible risque détecté (ANN)") def batch_prediction_page(): st.title("📁 Prédiction depuis un Fichier CSV") uploaded_file = st.file_uploader("Charger un fichier CSV", type="csv") if uploaded_file: try: data = pd.read_csv(uploaded_file) X_scaled = scaler.transform(data) preds = model.predict(X_scaled) probas = model.predict_proba(X_scaled) data["Décès prédit"] = preds data["Probabilité de décès"] = np.round(probas[:, 1] * 100, 2) st.dataframe(data) st.download_button("📥 Télécharger résultats", data.to_csv(index=False), "resultats.csv") except Exception as e: st.error(f"Erreur lors du traitement : {e}") def history_page(): st.title("📚 Historique de Prédictions") if "history" in st.session_state and st.session_state["history"]: hist_df = pd.DataFrame(st.session_state["history"]) st.dataframe(hist_df) else: st.info("Aucune prédiction enregistrée dans cette session.") pages = { "🏠 Accueil": home, "🔍 Prédiction (Classique)": prediction_page, "🤖 Prédiction Deep Learning": ann_prediction_page, "📁 Prédiction en lot": batch_prediction_page, "📚 Historique": history_page } choice = st.sidebar.radio("Navigation", list(pages.keys())) pages[choice]()