Files changed (1) hide show
  1. app.py +247 -75
app.py CHANGED
@@ -5,95 +5,267 @@ import seaborn as sns
5
  import matplotlib.pyplot as plt
6
  from sklearn.metrics import classification_report, confusion_matrix, accuracy_score
7
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
8
  # ----------- Fonctions utiles -----------
9
  @st.cache_data
10
  def load_csv_file(file_path):
11
  return pd.read_csv(file_path)
12
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
  # ----------- Sidebar -----------
14
- st.sidebar.header("🛠️ Paramètres")
15
- room_path_dataSet = st.sidebar.text_input("📁 Chemin Dataset (.csv)", "data/Dataset/dataset.csv")
16
- y_true_path = st.sidebar.text_input("📂 y_true.npy", "data/Dataset/y_true.npy")
17
- y_pred_path = st.sidebar.text_input("📂 y_pred.npy", "data/Dataset/y_pred.npy")
18
- gwo_results_path = st.sidebar.text_input("📂 Résultats GWO.csv", "data/Dataset/gwo_results.csv")
19
-
20
- load_data_btn = st.sidebar.button("📥 Charger les fichiers")
21
- evaluate_btn = st.sidebar.button("🚀 Lancer l'Évaluation")
22
-
23
- st.title("📊 Dashboard - Évaluation CSI & Deep Learning")
24
-
25
- # ----------- Tabs -----------
26
- tabs = st.tabs(["📊 Données CSI", "⚙️ Résultats GWO", "📈 Évaluation du Modèle", "📤 Upload Utilisateur"])
27
-
28
- if load_data_btn or evaluate_btn:
29
- try:
30
- dataset = load_csv_file(room_path_dataSet)
31
- y_true = np.load(y_true_path, allow_pickle=True)
32
- y_pred = np.load(y_pred_path, allow_pickle=True)
33
- results_df = pd.read_csv(gwo_results_path)
34
-
35
- with tabs[0]:
36
- st.subheader("📊 Aperçu du Dataset CSI")
37
- st.dataframe(dataset)
38
 
39
- with tabs[1]:
40
- st.subheader("⚙️ Résultats GWO")
41
- st.dataframe(results_df)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
42
 
43
- best_config = results_df.sort_values(by="val_loss").iloc[0]
44
- st.success("🏆 Meilleurs hyperparamètres (GWO)")
45
- st.write(best_config)
46
 
47
- st.subheader("📈 Courbe d'Accuracy par itération")
48
- fig1, ax1 = plt.subplots()
49
- ax1.plot(results_df["val_accuracy"], marker="o")
50
- ax1.set_xlabel("Itération")
51
- ax1.set_ylabel("Accuracy")
52
- ax1.grid(True)
53
- st.pyplot(fig1)
54
 
55
- with tabs[2]:
56
- st.subheader("📄 Rapport de Classification")
57
- report = classification_report(y_true, y_pred, output_dict=True)
58
- st.dataframe(pd.DataFrame(report).transpose())
59
-
60
- acc = accuracy_score(y_true, y_pred)
61
- st.metric("🎯 Accuracy Globale", f"{acc:.4f}")
62
-
63
- cm = confusion_matrix(y_true, y_pred)
64
- fig2, ax2 = plt.subplots()
65
- sns.heatmap(cm, annot=True, fmt="d", cmap="Blues", ax=ax2)
66
- ax2.set_title("Matrice de Confusion")
67
- ax2.set_xlabel("Prédit")
68
- ax2.set_ylabel("Réel")
69
- st.pyplot(fig2)
70
-
71
- with tabs[3]:
72
- st.subheader("📤 Upload de vos propres résultats")
73
-
74
- uploaded_fileX = st.file_uploader("📁 y_pred.npy", type=["npy"])
75
- uploaded_fileY = st.file_uploader("📁 y_true.npy", type=["npy"])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
76
 
77
- if uploaded_fileX is not None and uploaded_fileY is not None:
78
- y_pred_user = np.load(uploaded_fileX, allow_pickle=True)
79
- y_true_user = np.load(uploaded_fileY, allow_pickle=True)
 
80
 
81
- st.success("✅ Fichiers utilisateurs chargés")
 
 
82
 
83
- st.subheader("📄 Rapport personnalisé")
 
 
 
 
 
 
 
 
 
84
  report = classification_report(y_true_user, y_pred_user, output_dict=True)
85
  st.dataframe(pd.DataFrame(report).transpose())
86
-
87
  acc = accuracy_score(y_true_user, y_pred_user)
88
- st.metric("🎯 Accuracy Upload", f"{acc:.4f}")
89
-
 
 
90
  cm = confusion_matrix(y_true_user, y_pred_user)
91
- fig3, ax3 = plt.subplots()
92
- sns.heatmap(cm, annot=True, fmt="d", cmap="Purples", ax=ax3)
93
- ax3.set_title("Matrice de Confusion (Upload)")
94
- ax3.set_xlabel("Prédit")
95
- ax3.set_ylabel("Réel")
96
- st.pyplot(fig3)
 
 
 
 
 
 
 
97
 
98
- except Exception as e:
99
- st.error(f"❌ Une erreur est survenue : {e}")
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
5
  import matplotlib.pyplot as plt
6
  from sklearn.metrics import classification_report, confusion_matrix, accuracy_score
7
 
8
+ # Configuration de la page
9
+ st.set_page_config(page_title="CSI Activity Recognition", layout="wide")
10
+
11
+ st.markdown("""
12
+ <style>
13
+ .sidebar-title {
14
+
15
+ font-size: 24px;
16
+ font-weight: bold;
17
+ margin-bottom: 20px;
18
+ }
19
+ .sidebar-subheader {
20
+ color: #de2e03;
21
+ font-size: 18px;
22
+ font-weight: bold;
23
+ margin-top: 20px;
24
+ margin-bottom: 10px;
25
+ }
26
+ .sidebar-footer {
27
+
28
+ font-weight: bold;
29
+ }
30
+ </style>
31
+ """, unsafe_allow_html=True)
32
+
33
  # ----------- Fonctions utiles -----------
34
  @st.cache_data
35
  def load_csv_file(file_path):
36
  return pd.read_csv(file_path)
37
+ # Fonction pour créer une matrice de confusion de taille réduite
38
+ def plot_confusion_matrix(cm, title="Matrice de Confusion"):
39
+ # Réduire la taille de la figure
40
+ fig, ax = plt.subplots(figsize=(5, 4)) # Taille réduite (était 8, 6)
41
+
42
+ # Créer le heatmap avec des paramètres ajustés
43
+ sns.heatmap(
44
+ cm,
45
+ annot=True, # Afficher les valeurs
46
+ fmt="d", # Format entier
47
+ cmap="Purples", # Palette de couleurs
48
+ ax=ax,
49
+ cbar=False, # Supprimer la barre de couleur pour gagner de l'espace
50
+ annot_kws={"size": 8} # Réduire la taille des annotations
51
+ )
52
+
53
+ # Configurer les titres et labels
54
+ ax.set_title(title, fontsize=10)
55
+ ax.set_xlabel("Prédit", fontsize=8)
56
+ ax.set_ylabel("Réel", fontsize=8)
57
+
58
+ # Réduire la taille des ticks
59
+ ax.tick_params(axis='both', which='major', labelsize=7)
60
+
61
+ # Ajuster l'espacement
62
+ plt.tight_layout()
63
+
64
+ return fig
65
  # ----------- Sidebar -----------
66
+ with st.sidebar:
67
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
68
 
69
+
70
+ # Image petite et centrée
71
+ col1, col2, col3 = st.sidebar.columns([1, 2, 1])
72
+ with col2:
73
+ st.image("cerveau.png", width=100)
74
+ # Custom colored title instead of st.title
75
+ st.markdown('<p class="sidebar-title">Paramètres</p>', unsafe_allow_html=True)
76
+
77
+ # Custom colored subheader instead of st.subheader
78
+ st.markdown('<p class="sidebar-subheader">Chemins des fichiers</p>', unsafe_allow_html=True)
79
+ room_path_dataSet = st.text_input("Dataset (.csv)", "data/Dataset/dataset.csv")
80
+ y_true_path = "data/Dataset/y_true.npy"
81
+ y_pred_path = "data/Dataset/y_pred.npy"
82
+ gwo_results_path = "data/Dataset/gwo_results.csv"
83
+
84
+ # Custom colored subheader
85
+ st.markdown('<p class="sidebar-subheader">Téléchargement personnalisé</p>', unsafe_allow_html=True)
86
+ uploaded_fileX = st.file_uploader("y_pred.npy", type=["npy"])
87
+ uploaded_fileY = st.file_uploader("y_true.npy", type=["npy"])
88
+
89
+ st.markdown("---")
90
+
91
 
 
 
 
92
 
93
+ # ----------- Main Content -----------
94
+ st.title(" Évaluation complète du Modèle")
95
+ st.markdown("Analyse des performances du modèle de reconnaissance d'activités CSI")
 
 
 
 
96
 
97
+ # Bouton principal de lancement
98
+ if st.button("🚀 Lancer l'Évaluation Complète", type="primary"):
99
+ with st.spinner("Analyse en cours..."):
100
+ try:
101
+ # Chargement des données
102
+ y_true = np.load(y_true_path, allow_pickle=True)
103
+ y_pred = np.load(y_pred_path, allow_pickle=True)
104
+ results_df = pd.read_csv(gwo_results_path)
105
+ dataset = load_csv_file(room_path_dataSet)
106
+
107
+ # Création des onglets
108
+ tab1, tab2, tab3, tab4, tab5 = st.tabs([
109
+ "📂 Décomposition des Données",
110
+ "🧬 Résultats GWO",
111
+ "📈 Évolution Accuracy",
112
+ "📊 Rapport de Classification",
113
+ "🔢 Matrice de Confusion"
114
+ ])
115
+
116
+ # Onglet 1: Décomposition des données
117
+ with tab1:
118
+ st.header("Aperçu du Dataset")
119
+ st.dataframe(dataset.head())
120
+ st.markdown("---")
121
+ st.header("Statistiques descriptives")
122
+ st.dataframe(dataset.describe())
123
+ # Dans l'onglet 2: Résultats GWO
124
+ with tab2:
125
+ st.header("Résultats d'optimisation GWO")
126
+ st.dataframe(results_df)
127
+ st.markdown("---")
128
+ st.header("Meilleurs hyperparamètres")
129
+ best_config = results_df.sort_values(by="val_loss").iloc[0]
130
+ # Création d'un dataframe pour une meilleure présentation
131
+ best_params_df = pd.DataFrame({
132
+ 'Paramètre': best_config.index,
133
+ 'Valeur': best_config.values
134
+ }).reset_index(drop=True)
135
+ # Style du tableau
136
+ st.dataframe(
137
+ best_params_df.style
138
+ .set_properties(**{
139
+ 'border': '1px solid #dee2e6'})
140
+ .highlight_max(subset=['Valeur'],color='#de2e03')
141
+ .highlight_min(subset=['Valeur'],color='#de2e03'),
142
+ height=(len(best_params_df) + 1) * 35 + 3,
143
+ use_container_width=True
144
+ )# Métriques en dessous
145
+ col1, col2 = st.columns(2)
146
+ with col1:
147
+ st.metric("Meilleure accuracy", f"{best_config['val_accuracy']:.4f}")
148
+ with col2:
149
+ st.metric("Plus faible loss", f"{best_config['val_loss']:.4f}")
150
+
151
+
152
+
153
+
154
+
155
+ # Onglet 3: Évolution Accuracy
156
+ with tab3:
157
+ st.header("Progression de l'accuracy")
158
+ fig, ax = plt.subplots(figsize=(10, 5))
159
+ ax.plot(results_df["val_accuracy"], marker="o", linestyle="-", color="#6366F1")
160
+ ax.set_xlabel("Itérations")
161
+ ax.set_ylabel("Accuracy")
162
+ ax.grid(True, alpha=0.3)
163
+ st.pyplot(fig)
164
+
165
+
166
+
167
+ # Onglet 4: Rapport de classification
168
+ with tab4:
169
+ st.header("Rapport de classification détaillé")
170
+ report = classification_report(y_true, y_pred, output_dict=True)
171
+ st.dataframe(pd.DataFrame(report).transpose())
172
+
173
+ st.markdown("---")
174
+ st.header("Metrics globales")
175
+ acc = accuracy_score(y_true, y_pred)
176
+ col1, col2, col3 = st.columns(3)
177
+ with col1:
178
+ st.metric("Accuracy", f"{acc:.2%}")
179
+ with col2:
180
+ st.metric("Précision moyenne", f"{report['weighted avg']['precision']:.2%}")
181
+ with col3:
182
+ st.metric("Rappel moyen", f"{report['weighted avg']['recall']:.2%}")
183
+
184
+ # Onglet 5: Matrice de confusion
185
+ with tab5:
186
+ st.header("Matrice de confusion")
187
+ cm = confusion_matrix(y_true, y_pred)
188
+
189
+ # Utiliser des colonnes pour contraindre la largeur
190
+ col1, col2, col3 = st.columns([1, 2, 1])
191
+ with col2:
192
+ # Utiliser notre fonction personnalisée pour créer une matrice plus petite
193
+ fig = plot_confusion_matrix(cm)
194
+ st.pyplot(fig)
195
+
196
+
197
+
198
+
199
 
200
+ except FileNotFoundError as e:
201
+ st.error(f"❌ Fichier non trouvé : {e}")
202
+ except Exception as e:
203
+ st.error(f"❌ Erreur : {e}")
204
 
205
+ # Section pour l'upload personnalisé
206
+ st.divider()
207
+ st.header("📤 Évaluation avec vos propres fichiers")
208
 
209
+ if uploaded_fileX is not None and uploaded_fileY is not None:
210
+ with st.spinner("Analyse en cours..."):
211
+ try:
212
+ y_pred_user = np.load(uploaded_fileX, allow_pickle=True)
213
+ y_true_user = np.load(uploaded_fileY, allow_pickle=True)
214
+
215
+ tab_user1, tab_user2 = st.tabs(["Rapport de Classification", "Matrice de Confusion"])
216
+
217
+ with tab_user1:
218
+ st.header("Rapport de classification")
219
  report = classification_report(y_true_user, y_pred_user, output_dict=True)
220
  st.dataframe(pd.DataFrame(report).transpose())
221
+
222
  acc = accuracy_score(y_true_user, y_pred_user)
223
+ st.metric("Accuracy Globale", f"{acc:.2%}")
224
+
225
+ with tab_user2:
226
+ st.header("Matrice de confusion")
227
  cm = confusion_matrix(y_true_user, y_pred_user)
228
+
229
+ # Utiliser des colonnes pour contraindre la largeur
230
+ col1, col2, col3 = st.columns([1, 2, 1])
231
+ with col2:
232
+ # Utiliser notre fonction personnalisée pour créer une matrice plus petite
233
+ fig = plot_confusion_matrix(cm, "Matrice de Confusion (Upload)")
234
+ st.pyplot(fig)
235
+
236
+
237
+ except Exception as e:
238
+ st.error(f"❌ Erreur : {e}")
239
+ else:
240
+ st.info("ℹ️ Veuillez télécharger vos fichiers dans la sidebar")
241
 
242
+ # Style CSS pour la sidebar
243
+ st.markdown("""
244
+ <style>
245
+ /* Titre principal */
246
+ .sidebar .title {
247
+ color: #FF4B4B !important; /* Rouge-orange Streamlit */
248
+ font-size: 1.5em !important;
249
+ }
250
+
251
+ /* Sous-titres */
252
+ .sidebar .stSubheader {
253
+ color: #FF6B6B !important; /* Orange plus clair */
254
+ font-size: 1.2em !important;
255
+ border-bottom: 1px solid #FF4B4B;
256
+ padding-bottom: 5px;
257
+ }
258
+
259
+ /* Textes des widgets */
260
+ .sidebar .stTextInput label,
261
+ .sidebar .stFileUploader label {
262
+ color: #555555 !important; /* Gris foncé */
263
+ font-weight: 500 !important;
264
+ }
265
+
266
+ /* Texte des informations */
267
+ .sidebar .stMarkdown {
268
+ color: #777777 !important; /* Gris moyen */
269
+ }
270
+ </style>
271
+ """, unsafe_allow_html=True)