DavidNgoue commited on
Commit
392c893
·
verified ·
1 Parent(s): 77889df

Upload 2 files

Browse files
Files changed (2) hide show
  1. app.py +379 -0
  2. best_model.pkl +3 -0
app.py ADDED
@@ -0,0 +1,379 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import numpy as np
4
+ import pickle
5
+ from PIL import Image
6
+ import plotly.express as px
7
+ import plotly.graph_objects as go
8
+ from streamlit_lottie import st_lottie
9
+ import requests
10
+ import json
11
+ from streamlit_option_menu import option_menu
12
+ import time
13
+
14
+
15
+ # Ajoutez ceci au début du code, juste après les imports
16
+ @st.cache_resource
17
+ def load_model():
18
+ """
19
+ Charge le modèle sauvegardé
20
+ """
21
+ try:
22
+ with open('models/best_model.pkl', 'rb') as f:
23
+ model = pickle.load(f)
24
+ return model
25
+ except Exception as e:
26
+ st.error(f"Erreur lors du chargement du modèle: {str(e)}")
27
+ return None
28
+
29
+
30
+ # Configuration de la page
31
+ st.set_page_config(
32
+ page_title="HeartGuard AI - Prédiction de Risque Cardiaque",
33
+ page_icon="❤️",
34
+ layout="wide",
35
+ initial_sidebar_state="expanded"
36
+ )
37
+
38
+ # Style CSS personnalisé
39
+ st.markdown("""
40
+ <style>
41
+ @import url('https://fonts.googleapis.com/css2?family=Poppins:wght@300;400;500;600;700&display=swap');
42
+
43
+ * {
44
+ font-family: 'Poppins', sans-serif;
45
+ }
46
+
47
+ .main {
48
+ background: linear-gradient(135deg, #f5f7fa 0%, #e4e8eb 100%);
49
+ }
50
+
51
+ .stButton>button {
52
+ background: linear-gradient(45deg, #ff4b4b, #ff6b6b);
53
+ color: white;
54
+ border-radius: 25px;
55
+ padding: 10px 25px;
56
+ border: none;
57
+ box-shadow: 0 4px 15px rgba(255, 75, 75, 0.3);
58
+ transition: all 0.3s ease;
59
+ }
60
+
61
+ .stButton>button:hover {
62
+ transform: translateY(-2px);
63
+ box-shadow: 0 6px 20px rgba(255, 75, 75, 0.4);
64
+ }
65
+
66
+ .sidebar .sidebar-content {
67
+ background: linear-gradient(180deg, #ffffff 0%, #f8f9fa 100%);
68
+ box-shadow: 2px 0 10px rgba(0,0,0,0.1);
69
+ }
70
+
71
+ .stSelectbox, .stNumberInput {
72
+ border-radius: 10px;
73
+ }
74
+
75
+ .css-1d391kg {
76
+ padding: 2rem 1rem;
77
+ }
78
+
79
+ .stProgress > div > div {
80
+ background-color: #ff4b4b;
81
+ }
82
+
83
+ .stMarkdown {
84
+ color: #2c3e50;
85
+ }
86
+
87
+ .stAlert {
88
+ border-radius: 10px;
89
+ }
90
+
91
+ .css-1v0mbdj {
92
+ border-radius: 10px;
93
+ }
94
+ </style>
95
+ """, unsafe_allow_html=True)
96
+
97
+ # Fonction pour charger les animations Lottie
98
+ def load_lottieurl(url: str):
99
+ r = requests.get(url)
100
+ if r.status_code != 200:
101
+ return None
102
+ return r.json()
103
+
104
+ # Chargement des animations
105
+ heart_animation = load_lottieurl("https://assets5.lottiefiles.com/packages/lf20_49rdyysj.json")
106
+ loading_animation = load_lottieurl("https://assets3.lottiefiles.com/packages/lf20_p8bfn5to.json")
107
+
108
+ # Sidebar avec menu stylisé
109
+ with st.sidebar:
110
+ st_lottie(heart_animation, height=150, key="sidebar_animation")
111
+
112
+ selected = option_menu(
113
+ menu_title="Navigation",
114
+ options=["Accueil", "Prédiction", "À Propos"],
115
+ icons=['house', 'heart-pulse', 'info-circle'],
116
+ menu_icon="cast",
117
+ default_index=0,
118
+ styles={
119
+ "container": {"padding": "0!important", "background-color": "#ffffff"},
120
+ "icon": {"color": "#ff4b4b", "font-size": "20px"},
121
+ "nav-link": {
122
+ "font-size": "16px",
123
+ "text-align": "left",
124
+ "margin": "0px",
125
+ "padding": "10px",
126
+ "--hover-color": "#ff4b4b",
127
+ },
128
+ "nav-link-selected": {"background-color": "#ff4b4b"},
129
+ }
130
+ )
131
+
132
+ # Contenu principal
133
+ if selected == "Accueil":
134
+ st.title("❤️ HeartGuard AI")
135
+ st.markdown("### Votre Assistant de Santé Cardiaque Intelligent")
136
+
137
+ col1, col2 = st.columns([2, 1])
138
+ with col1:
139
+ st.markdown("""
140
+ Bienvenue dans HeartGuard AI, votre outil de prédiction de risque cardiaque basé sur l'intelligence artificielle.
141
+
142
+ Notre application utilise des algorithmes avancés de machine learning pour évaluer votre risque cardiaque
143
+ en fonction de plusieurs paramètres de santé.
144
+
145
+ ### Fonctionnalités principales :
146
+ - 🔍 Analyse précise des facteurs de risque
147
+ - 📊 Visualisations interactives
148
+ - 🎯 Prédictions en temps réel
149
+ - 📱 Interface intuitive et moderne
150
+ """)
151
+
152
+ with col2:
153
+ st_lottie(heart_animation, height=300, key="main_animation")
154
+
155
+ elif selected == "Prédiction":
156
+ st.title("Prédiction de Risque Cardiaque")
157
+
158
+ # Formulaire de prédiction avec animation de chargement
159
+ with st.form("prediction_form"):
160
+ col1, col2 = st.columns(2)
161
+
162
+ with col1:
163
+ st.subheader("Informations Personnelles")
164
+ age = st.number_input("Âge", min_value=0, max_value=120, value=50)
165
+ male = st.selectbox("Genre", ["Femme", "Homme"])
166
+ male = 1 if male == "Homme" else 0
167
+
168
+ st.subheader("Mode de Vie")
169
+ current_smoker = st.selectbox("Fumeur actuel", ["Non", "Oui"])
170
+ current_smoker = 1 if current_smoker == "Oui" else 0
171
+ cigs_per_day = st.number_input("Nombre de cigarettes par jour", min_value=0, max_value=100, value=0)
172
+
173
+ with col2:
174
+ st.subheader("Paramètres de Santé")
175
+ bp_meds = st.selectbox("Médicaments pour la tension", ["Non", "Oui"])
176
+ bp_meds = 1 if bp_meds == "Oui" else 0
177
+ diabetes = st.selectbox("Diabète", ["Non", "Oui"])
178
+ diabetes = 1 if diabetes == "Oui" else 0
179
+ tot_chol = st.number_input("Cholestérol total", min_value=0, max_value=700, value=200)
180
+ sys_bp = st.number_input("Pression artérielle systolique", min_value=0, max_value=300, value=120)
181
+ dia_bp = st.number_input("Pression artérielle diastolique", min_value=0, max_value=200, value=80)
182
+ bmi = st.number_input("IMC", min_value=0.0, max_value=100.0, value=25.0)
183
+ heart_rate = st.number_input("Fréquence cardiaque", min_value=0, max_value=200, value=75)
184
+ glucose = st.number_input("Glucose", min_value=0, max_value=400, value=80)
185
+
186
+ submit_button = st.form_submit_button("Analyser le Risque")
187
+
188
+ if submit_button:
189
+ with st.spinner("Analyse en cours..."):
190
+ st_lottie(loading_animation, height=100, key="loading")
191
+
192
+ # Préparation des données
193
+ input_data = pd.DataFrame({
194
+ 'male': [male],
195
+ 'age': [age],
196
+ 'currentSmoker': [current_smoker],
197
+ 'cigsPerDay': [cigs_per_day],
198
+ 'BPMeds': [bp_meds],
199
+ 'diabetes': [diabetes],
200
+ 'totChol': [tot_chol],
201
+ 'sysBP': [sys_bp],
202
+ 'diaBP': [dia_bp],
203
+ 'BMI': [bmi],
204
+ 'heartRate': [heart_rate],
205
+ 'glucose': [glucose]
206
+ })
207
+
208
+ # Chargement et prédiction
209
+ model = load_model()
210
+ prediction = model.predict(input_data)[0]
211
+ probability = model.predict_proba(input_data)[0]
212
+
213
+ # Affichage des résultats avec animations
214
+ st.markdown("---")
215
+ col1, col2, col3 = st.columns(3)
216
+
217
+ with col1:
218
+ st.subheader("Résultat de l'Analyse")
219
+ if prediction == 0:
220
+ st.success("Risque Cardiaque: Faible")
221
+ else:
222
+ st.error("Risque Cardiaque: Élevé")
223
+
224
+ with col2:
225
+ st.subheader("Probabilité de Risque")
226
+ fig = go.Figure(go.Indicator(
227
+ mode="gauge+number+delta",
228
+ value=probability[1]*100,
229
+ domain={'x': [0, 1], 'y': [0, 1]},
230
+ title={'text': "Probabilité (%)"},
231
+ gauge={
232
+ 'axis': {'range': [0, 100]},
233
+ 'bar': {'color': "darkblue"},
234
+ 'steps': [
235
+ {'range': [0, 30], 'color': "lightgreen"},
236
+ {'range': [30, 70], 'color': "yellow"},
237
+ {'range': [70, 100], 'color': "red"}
238
+ ],
239
+ 'threshold': {
240
+ 'line': {'color': "red", 'width': 4},
241
+ 'thickness': 0.75,
242
+ 'value': 50
243
+ }
244
+ }))
245
+ st.plotly_chart(fig, use_container_width=True)
246
+
247
+ with col3:
248
+ st.subheader("Facteurs de Risque")
249
+ risk_factors = []
250
+ if age > 60: risk_factors.append("Âge avancé")
251
+ if current_smoker: risk_factors.append("Tabagisme")
252
+ if bp_meds: risk_factors.append("Hypertension")
253
+ if diabetes: risk_factors.append("Diabète")
254
+ if bmi > 30: risk_factors.append("Obésité")
255
+ if tot_chol > 240: risk_factors.append("Cholestérol élevé")
256
+
257
+ if risk_factors:
258
+ for factor in risk_factors:
259
+ st.warning(factor)
260
+ else:
261
+ st.info("Aucun facteur de risque majeur identifié")
262
+
263
+ elif selected == "À Propos":
264
+ st.markdown("""
265
+ <style>
266
+ .about-container {
267
+ max-width: 800px;
268
+ margin: 0 auto;
269
+ padding: 20px;
270
+ background: white;
271
+ border-radius: 15px;
272
+ box-shadow: 0 4px 6px rgba(0, 0, 0, 0.1);
273
+ }
274
+ .title {
275
+ color: #2c3e50;
276
+ font-size: 2.5em;
277
+ text-align: center;
278
+ margin-bottom: 30px;
279
+ font-weight: 600;
280
+ }
281
+ .description {
282
+ color: #555;
283
+ font-size: 1.1em;
284
+ line-height: 1.6;
285
+ text-align: center;
286
+ margin-bottom: 40px;
287
+ padding: 0 20px;
288
+ }
289
+ .profile-container {
290
+ display: flex;
291
+ flex-direction: column;
292
+ align-items: center;
293
+ gap: 20px;
294
+ padding: 20px;
295
+ }
296
+ .profile-image {
297
+ width: 200px;
298
+ height: 200px;
299
+ border-radius: 50%;
300
+ border: 4px solid #ff4b4b;
301
+ box-shadow: 0 4px 8px rgba(0, 0, 0, 0.2);
302
+ object-fit: cover;
303
+ }
304
+ .profile-info {
305
+ text-align: center;
306
+ }
307
+ .profile-info h4 {
308
+ color: #2c3e50;
309
+ font-size: 1.8em;
310
+ margin: 10px 0;
311
+ }
312
+ .contact-info {
313
+ display: flex;
314
+ flex-direction: column;
315
+ gap: 10px;
316
+ align-items: center;
317
+ margin-top: 15px;
318
+ }
319
+ .contact-link {
320
+ display: flex;
321
+ align-items: center;
322
+ gap: 10px;
323
+ color: #555;
324
+ text-decoration: none;
325
+ padding: 8px 15px;
326
+ border-radius: 25px;
327
+ background: #f8f9fa;
328
+ transition: all 0.3s ease;
329
+ }
330
+ .contact-link:hover {
331
+ background: #ff4b4b;
332
+ color: white;
333
+ transform: translateY(-2px);
334
+ }
335
+ </style>
336
+
337
+ <div class="about-container">
338
+ <h1 class="title">Mon Parcours</h1>
339
+
340
+ <p class="description">
341
+ Je suis un passionné de l'intelligence artificielle et de la donnée.
342
+ Actuellement en Master 2 en IA et Big Data, je travaille sur des solutions
343
+ innovantes dans le domaine de l'Intelligence Artificielle appliquée à la santé.
344
+ </p>
345
+
346
+ <div class="profile-container">
347
+ <img src="https://avatars.githubusercontent.com/u/TheBeyonder237"
348
+ alt="Ngoue David"
349
+ class="profile-image">
350
+
351
+ <div class="profile-info">
352
+ <h4>Ngoue David</h4>
353
+
354
+ <div class="contact-info">
355
+ <a href="mailto:ngouedavidrogeryannick@gmail.com" class="contact-link">
356
+ 📧 ngouedavidrogeryannick@gmail.com
357
+ </a>
358
+ <a href="https://github.com/TheBeyonder237" target="_blank" class="contact-link">
359
+ 🌐 Profil GitHub
360
+ </a>
361
+ <div class="contact-link">
362
+ 🎓 Master 2 IA & Big Data
363
+ </div>
364
+ </div>
365
+ </div>
366
+ </div>
367
+ </div>
368
+ """, unsafe_allow_html=True)
369
+
370
+ # Ajout d'une animation Lottie
371
+ st_lottie(heart_animation, height=200, key="about_animation")
372
+
373
+ # Footer
374
+ st.markdown("""
375
+ <div style="text-align: center; margin-top: 30px; color: #666;">
376
+ <p>Développé avec ❤️ par Ngoue David</p>
377
+ <p style="font-size: 0.8em;">© 2024 HeartGuard AI. Tous droits réservés.</p>
378
+ </div>
379
+ """, unsafe_allow_html=True)
best_model.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:f1eb3c39a9a250d346ec0818bb84b68eb9790c19e977e35c3da21d031312ba85
3
+ size 7392293