analist commited on
Commit
407f7b6
·
verified ·
1 Parent(s): 4c41588

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +181 -1
app.py CHANGED
@@ -100,6 +100,175 @@ def plot_feature_importance(model, feature_names, model_type):
100
  plt.title(f"Feature Importance - {model_type}")
101
  return plt.gcf()
102
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
103
  def app():
104
  st.title("Interpréteur de Modèles ML")
105
 
@@ -123,7 +292,8 @@ def app():
123
  ["Performance des modèles",
124
  "Interprétation du modèle",
125
  "Analyse des caractéristiques",
126
- "Simulateur de prédictions"]
 
127
  )
128
 
129
  current_model = st.session_state.model_results[selected_model]['model']
@@ -195,6 +365,16 @@ def app():
195
  fig, ax = plt.subplots(figsize=(10, 8))
196
  sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', center=0)
197
  st.pyplot(fig)
 
 
 
 
 
 
 
 
 
 
198
 
199
  # Simulateur de prédictions
200
  else:
 
100
  plt.title(f"Feature Importance - {model_type}")
101
  return plt.gcf()
102
 
103
+ def prepare_clustering_data(data, numeric_columns):
104
+ scaler = StandardScaler()
105
+ scaled_features = scaler.fit_transform(data[numeric_columns])
106
+ return scaled_features, scaler
107
+
108
+ def perform_clustering(scaled_features, n_clusters):
109
+ kmeans = KMeans(n_clusters=n_clusters, random_state=42)
110
+ cluster_labels = kmeans.fit_predict(scaled_features)
111
+ return kmeans, cluster_labels
112
+
113
+ def plot_clusters_3d(data, labels, features, product_category):
114
+ pca = PCA(n_components=3)
115
+ components = pca.fit_transform(data)
116
+
117
+ df_plot = pd.DataFrame({
118
+ 'PC1': components[:, 0],
119
+ 'PC2': components[:, 1],
120
+ 'PC3': components[:, 2],
121
+ 'Cluster': [f"Groupe {i}" for i in labels]
122
+ })
123
+
124
+ fig = px.scatter_3d(
125
+ df_plot,
126
+ x='PC1',
127
+ y='PC2',
128
+ z='PC3',
129
+ color='Cluster',
130
+ title=f'Analyse des sous-groupes pour {product_category}',
131
+ labels={
132
+ 'PC1': 'Composante 1',
133
+ 'PC2': 'Composante 2',
134
+ 'PC3': 'Composante 3'
135
+ }
136
+ )
137
+
138
+ fig.update_layout(
139
+ scene=dict(
140
+ xaxis_title='Composante 1',
141
+ yaxis_title='Composante 2',
142
+ zaxis_title='Composante 3'
143
+ ),
144
+ legend_title_text='Sous-groupes'
145
+ )
146
+
147
+ return fig
148
+
149
+ def analyze_clusters(data, cluster_labels, numeric_columns, product_category):
150
+ data_with_clusters = data.copy()
151
+ data_with_clusters['Cluster'] = cluster_labels
152
+
153
+ cluster_stats = []
154
+ for cluster in range(len(np.unique(cluster_labels))):
155
+ cluster_data = data_with_clusters[data_with_clusters['Cluster'] == cluster]
156
+ stats = {
157
+ 'Cluster': cluster,
158
+ 'Taille': len(cluster_data),
159
+ 'Product': product_category,
160
+ 'Caractéristiques principales': {}
161
+ }
162
+
163
+ for col in numeric_columns:
164
+ stats['Caractéristiques principales'][col] = cluster_data[col].mean()
165
+
166
+ cluster_stats.append(stats)
167
+
168
+ return cluster_stats
169
+
170
+ def add_clustering_analysis(data):
171
+ st.header("Analyse par Clustering des Produits Acceptés")
172
+
173
+ if data is None:
174
+ st.error("Veuillez charger des données pour l'analyse")
175
+ return
176
+
177
+ # Filtrer uniquement les clients ayant accepté un produit
178
+ accepted_data = data[data['ProdTaken'] == 1]
179
+
180
+ if len(accepted_data) == 0:
181
+ st.error("Aucune donnée trouvée pour les produits acceptés")
182
+ return
183
+
184
+ st.write(f"Nombre total de produits acceptés: {len(accepted_data)}")
185
+
186
+ # Obtenir les différents types de produits proposés
187
+ product_types = accepted_data['ProductPitched'].unique()
188
+ st.write(f"Types de produits disponibles: {', '.join(product_types)}")
189
+
190
+ # Sélection des caractéristiques pour le clustering
191
+ numeric_columns = st.multiselect(
192
+ "Sélectionner les caractéristiques pour l'analyse",
193
+ data.select_dtypes(include=['float64', 'int64']).columns,
194
+ help="Choisissez les caractéristiques numériques pertinentes pour l'analyse"
195
+ )
196
+
197
+ if numeric_columns:
198
+ for product in product_types:
199
+ st.subheader(f"\nAnalyse du produit: {product}")
200
+
201
+ product_data = accepted_data[accepted_data['ProductPitched'] == product]
202
+ st.write(f"Nombre de clients ayant accepté ce produit: {len(product_data)}")
203
+
204
+ max_clusters = min(len(product_data) - 1, 10)
205
+ if max_clusters < 2:
206
+ st.warning(f"Pas assez de données pour le clustering du produit {product}")
207
+ continue
208
+
209
+ n_clusters = st.slider(
210
+ f"Nombre de sous-groupes pour {product}",
211
+ 2, max_clusters,
212
+ min(3, max_clusters),
213
+ key=f"slider_{product}"
214
+ )
215
+
216
+ scaled_features, _ = prepare_clustering_data(product_data, numeric_columns)
217
+ kmeans, cluster_labels = perform_clustering(scaled_features, n_clusters)
218
+
219
+ silhouette_avg = silhouette_score(scaled_features, cluster_labels)
220
+ st.write(f"Score de silhouette: {silhouette_avg:.3f}")
221
+
222
+ fig = plot_clusters_3d(scaled_features, cluster_labels, numeric_columns, product)
223
+ st.plotly_chart(fig)
224
+
225
+ st.write("### Caractéristiques des sous-groupes")
226
+ cluster_stats = analyze_clusters(product_data, cluster_labels, numeric_columns, product)
227
+
228
+ global_means = product_data[numeric_columns].mean()
229
+
230
+ for stats in cluster_stats:
231
+ st.write(f"\n**Sous-groupe {stats['Cluster']} ({stats['Taille']} clients)**")
232
+
233
+ comparison_data = []
234
+ for feat, value in stats['Caractéristiques principales'].items():
235
+ global_mean = global_means[feat]
236
+ diff_percent = ((value - global_mean) / global_mean * 100)
237
+ comparison_data.append({
238
+ 'Caractéristique': feat,
239
+ 'Valeur moyenne du groupe': f"{value:.2f}",
240
+ 'Moyenne globale': f"{global_mean:.2f}",
241
+ 'Différence (%)': f"{diff_percent:+.1f}%"
242
+ })
243
+
244
+ comparison_df = pd.DataFrame(comparison_data)
245
+ st.table(comparison_df)
246
+
247
+ st.write("### Recommandations marketing")
248
+ distinctive_features = []
249
+ for col in numeric_columns:
250
+ cluster_mean = product_data[cluster_labels == stats['Cluster']][col].mean()
251
+ global_mean = product_data[col].mean()
252
+ diff_percent = ((cluster_mean - global_mean) / global_mean * 100)
253
+
254
+ if abs(diff_percent) > 10:
255
+ distinctive_features.append({
256
+ 'feature': col,
257
+ 'diff': diff_percent,
258
+ 'value': cluster_mean
259
+ })
260
+
261
+ if distinctive_features:
262
+ recommendations = [
263
+ f"- Groupe avec {feat['feature']} {'supérieur' if feat['diff'] > 0 else 'inférieur'} " \
264
+ f"à la moyenne ({feat['diff']:+.1f}%)"
265
+ for feat in distinctive_features
266
+ ]
267
+ st.write("\n".join(recommendations))
268
+ else:
269
+ st.write("- Pas de caractéristiques fortement distinctives identifiées")
270
+
271
+
272
  def app():
273
  st.title("Interpréteur de Modèles ML")
274
 
 
292
  ["Performance des modèles",
293
  "Interprétation du modèle",
294
  "Analyse des caractéristiques",
295
+ "Simulateur de prédictions",
296
+ "Analyse par Clustering"]
297
  )
298
 
299
  current_model = st.session_state.model_results[selected_model]['model']
 
365
  fig, ax = plt.subplots(figsize=(10, 8))
366
  sns.heatmap(corr_matrix, annot=True, cmap='coolwarm', center=0)
367
  st.pyplot(fig)
368
+
369
+ elif page == "Analyse par Clustering":
370
+ # Charger les données pour le clustering
371
+ uploaded_file = st.file_uploader("Charger les données pour le clustering (CSV)", type="csv")
372
+ if uploaded_file is not None:
373
+ data = pd.read_csv(uploaded_file)
374
+ add_clustering_analysis(data)
375
+ else:
376
+ st.warning("Veuillez charger un fichier CSV pour l'analyse par clustering")
377
+
378
 
379
  # Simulateur de prédictions
380
  else: