Eric2mangel commited on
Commit
174b3e4
·
verified ·
1 Parent(s): 1b3a103

Update app.py

Browse files

Suppression des jeux de données inutiles dans ce projet

Files changed (1) hide show
  1. app.py +218 -218
app.py CHANGED
@@ -1,219 +1,219 @@
1
- import streamlit as st
2
- import pandas as pd
3
- import numpy as np
4
- import seaborn as sns
5
- import matplotlib.pyplot as plt
6
- from scipy.stats import chi2_contingency
7
-
8
- # Configuration de la page
9
- st.set_page_config(
10
- page_title="Matrice V de Cramer",
11
- page_icon="📊",
12
- layout="wide"
13
- )
14
-
15
- # Fonction de calcul du V de Cramer
16
- def cramers_v(x, y):
17
- """
18
- Calcule le V de Cramer entre deux variables nominales (qualitatives).
19
- """
20
- confusion_matrix = pd.crosstab(x, y)
21
- chi2 = chi2_contingency(confusion_matrix)[0]
22
- n = confusion_matrix.sum().sum()
23
- phi2 = chi2 / n
24
- r, k = confusion_matrix.shape
25
- # Correction pour les petites tailles d'échantillon
26
- phi2_corrected = max(0, phi2 - ((k-1)*(r-1))/(n-1))
27
- r_corrected = r - ((r-1)**2)/(n-1)
28
- k_corrected = k - ((k-1)**2)/(n-1)
29
-
30
- return np.sqrt(phi2_corrected / min(k_corrected-1, r_corrected-1))
31
-
32
- # Fonction pour calculer la matrice
33
- def calculate_cramer_matrix(df, columns):
34
- """
35
- Calcule la matrice des V de Cramer pour les colonnes sélectionnées.
36
- """
37
- v_cramer_matrix = pd.DataFrame(index=columns, columns=columns)
38
-
39
- for col1 in columns:
40
- for col2 in columns:
41
- if col1 == col2:
42
- v_cramer_matrix.loc[col1, col2] = 1.0
43
- else:
44
- v_cramer = cramers_v(df[col1], df[col2])
45
- v_cramer_matrix.loc[col1, col2] = v_cramer
46
-
47
- return v_cramer_matrix.astype(float)
48
-
49
- # Titre de l'application
50
- st.title("📊 Matrice des V de Cramer")
51
- st.markdown("Analyse de l'association entre variables catégorielles")
52
-
53
- # Sidebar pour la sélection des données
54
- st.sidebar.header("Configuration")
55
-
56
- # Choix de la source de données
57
- data_source = st.sidebar.radio(
58
- "Source des données",
59
- ["Jeu de données Seaborn", "Importer un fichier"],
60
- label_visibility="visible"
61
- )
62
-
63
- df = None
64
-
65
- # Chargement des données
66
- if data_source == "Jeu de données Seaborn":
67
- # Liste des jeux de données disponibles
68
- seaborn_datasets = [
69
- 'titanic', 'tips', 'iris', 'penguins', 'diamonds',
70
- 'exercise', 'planets', 'mpg', 'taxis'
71
- ]
72
-
73
- selected_dataset = st.sidebar.selectbox(
74
- "Choisir un jeu de données",
75
- seaborn_datasets
76
- )
77
-
78
- try:
79
- df = sns.load_dataset(selected_dataset)
80
- st.sidebar.success(f"✅ Jeu '{selected_dataset}' chargé")
81
- except Exception as e:
82
- st.sidebar.error(f"Erreur : {e}")
83
-
84
- else:
85
- # Import de fichier
86
- uploaded_file = st.sidebar.file_uploader(
87
- "Importer un fichier CSV",
88
- type=['csv']
89
- )
90
-
91
- if uploaded_file is not None:
92
- try:
93
- # Détection automatique du séparateur avec engine='python'
94
- df = pd.read_csv(uploaded_file, sep=None, engine='python')
95
- st.sidebar.success("✅ Fichier importé")
96
- except Exception as e:
97
- st.sidebar.error(f"Erreur : {e}")
98
-
99
- # Traitement des données
100
- if df is not None:
101
- # Sélection des colonnes catégorielles
102
- categorical_cols = df.select_dtypes(include=['object', 'category', 'bool']).columns.tolist()
103
-
104
- # Ajouter les colonnes numériques avec peu de valeurs uniques
105
- numeric_cols = df.select_dtypes(include=['int64', 'float64']).columns
106
- for col in numeric_cols:
107
- if df[col].nunique() <= 10:
108
- categorical_cols.append(col)
109
-
110
- if len(categorical_cols) == 0:
111
- st.warning("⚠️ Aucune variable catégorielle détectée.")
112
- else:
113
- st.sidebar.write(f"**{len(categorical_cols)}** variables détectées")
114
-
115
- # Sélection des colonnes à analyser
116
- selected_cols = st.sidebar.multiselect(
117
- "Variables à analyser",
118
- categorical_cols,
119
- default=categorical_cols[:min(6, len(categorical_cols))]
120
- )
121
-
122
- if len(selected_cols) < 2:
123
- st.info("ℹ️ Veuillez sélectionner au moins 2 variables.")
124
- else:
125
- # Préparation des données
126
- df_cat = df[selected_cols].copy()
127
-
128
- # Options de traitement des valeurs manquantes
129
- nan_handling = st.sidebar.radio(
130
- "Valeurs manquantes",
131
- ["Remplacer par 'Missing'", "Supprimer les lignes"]
132
- )
133
-
134
- # Traitement des valeurs manquantes
135
- if nan_handling == "Remplacer par 'Missing'":
136
- for col in selected_cols:
137
- # Convertir d'abord en string pour éviter l'erreur avec les categories
138
- df_cat[col] = df_cat[col].astype(str)
139
- df_cat[col] = df_cat[col].replace('nan', 'Missing')
140
- df_cat[col] = df_cat[col].replace('None', 'Missing')
141
- df_cat[col] = df_cat[col].astype('category')
142
- else:
143
- df_cat = df_cat.dropna()
144
- # Convertir en category
145
- for col in selected_cols:
146
- df_cat[col] = df_cat[col].astype('category')
147
-
148
- # Calcul de la matrice
149
- if st.sidebar.button("🔄 Calculer", type="primary"):
150
- with st.spinner("Calcul en cours..."):
151
- v_cramer_matrix = calculate_cramer_matrix(df_cat, selected_cols)
152
-
153
- # Onglets pour organiser l'affichage
154
- tab1, tab2 = st.tabs(["📊 Visualisation", "📋 Données"])
155
-
156
- with tab1:
157
- col1, col2 = st.columns([2.5, 1])
158
-
159
- with col1:
160
- # Création de la heatmap (taille réduite)
161
- fig, ax = plt.subplots(figsize=(8, 6))
162
- sns.heatmap(
163
- v_cramer_matrix,
164
- annot=True,
165
- cmap='coolwarm',
166
- fmt=".2f",
167
- linewidths=0.5,
168
- cbar_kws={'label': 'V de Cramer'},
169
- ax=ax,
170
- vmin=0,
171
- vmax=1
172
- )
173
- plt.title('Matrice des V de Cramer', fontsize=12, pad=15)
174
- plt.tight_layout()
175
- st.pyplot(fig)
176
-
177
- with col2:
178
- st.markdown("**Interprétation :**")
179
- st.markdown("""
180
- - **0.0-0.1** : Très faible
181
- - **0.1-0.3** : Faible
182
- - **0.3-0.5** : Modérée
183
- - **0.5-0.7** : Forte
184
- - **0.7-1.0** : Très forte
185
- """)
186
-
187
- st.markdown("**Top 5 associations :**")
188
-
189
- # Extraire les valeurs uniques (triangle supérieur)
190
- associations = []
191
- for i, col1_name in enumerate(selected_cols):
192
- for j, col2_name in enumerate(selected_cols):
193
- if i < j:
194
- associations.append({
195
- 'Var 1': col1_name,
196
- 'Var 2': col2_name,
197
- 'V': v_cramer_matrix.loc[col1_name, col2_name]
198
- })
199
-
200
- if associations:
201
- top_assoc = pd.DataFrame(associations).sort_values(
202
- 'V', ascending=False
203
- ).head(5)
204
- st.dataframe(top_assoc, hide_index=True, height=210)
205
-
206
- with tab2:
207
- st.write(f"**Dimensions :** {df.shape[0]} lignes × {df.shape[1]} colonnes")
208
- st.dataframe(df.head(20), use_container_width=True)
209
-
210
- else:
211
- st.info("👈 Veuillez sélectionner ou importer un jeu de données.")
212
-
213
- # Footer
214
- st.markdown("---")
215
- st.markdown("""
216
- <div style='text-align: center; color: gray;'>
217
- <small>Le V de Cramer mesure l'association entre deux variables catégorielles (0 = aucune association, 1 = association parfaite)</small>
218
- </div>
219
  """, unsafe_allow_html=True)
 
1
+ import streamlit as st
2
+ import pandas as pd
3
+ import numpy as np
4
+ import seaborn as sns
5
+ import matplotlib.pyplot as plt
6
+ from scipy.stats import chi2_contingency
7
+
8
+ # Configuration de la page
9
+ st.set_page_config(
10
+ page_title="Matrice V de Cramer",
11
+ page_icon="📊",
12
+ layout="wide"
13
+ )
14
+
15
+ # Fonction de calcul du V de Cramer
16
+ def cramers_v(x, y):
17
+ """
18
+ Calcule le V de Cramer entre deux variables nominales (qualitatives).
19
+ """
20
+ confusion_matrix = pd.crosstab(x, y)
21
+ chi2 = chi2_contingency(confusion_matrix)[0]
22
+ n = confusion_matrix.sum().sum()
23
+ phi2 = chi2 / n
24
+ r, k = confusion_matrix.shape
25
+ # Correction pour les petites tailles d'échantillon
26
+ phi2_corrected = max(0, phi2 - ((k-1)*(r-1))/(n-1))
27
+ r_corrected = r - ((r-1)**2)/(n-1)
28
+ k_corrected = k - ((k-1)**2)/(n-1)
29
+
30
+ return np.sqrt(phi2_corrected / min(k_corrected-1, r_corrected-1))
31
+
32
+ # Fonction pour calculer la matrice
33
+ def calculate_cramer_matrix(df, columns):
34
+ """
35
+ Calcule la matrice des V de Cramer pour les colonnes sélectionnées.
36
+ """
37
+ v_cramer_matrix = pd.DataFrame(index=columns, columns=columns)
38
+
39
+ for col1 in columns:
40
+ for col2 in columns:
41
+ if col1 == col2:
42
+ v_cramer_matrix.loc[col1, col2] = 1.0
43
+ else:
44
+ v_cramer = cramers_v(df[col1], df[col2])
45
+ v_cramer_matrix.loc[col1, col2] = v_cramer
46
+
47
+ return v_cramer_matrix.astype(float)
48
+
49
+ # Titre de l'application
50
+ st.title("📊 Matrice des V de Cramer")
51
+ st.markdown("Analyse de l'association entre variables catégorielles")
52
+
53
+ # Sidebar pour la sélection des données
54
+ st.sidebar.header("Configuration")
55
+
56
+ # Choix de la source de données
57
+ data_source = st.sidebar.radio(
58
+ "Source des données",
59
+ ["Jeu de données Seaborn", "Importer un fichier"],
60
+ label_visibility="visible"
61
+ )
62
+
63
+ df = None
64
+
65
+ # Chargement des données
66
+ if data_source == "Jeu de données Seaborn":
67
+ # Liste des jeux de données disponibles
68
+ seaborn_datasets = [
69
+ 'titanic', 'tips', 'penguins', 'diamonds',
70
+ 'mpg', 'taxis'
71
+ ]
72
+
73
+ selected_dataset = st.sidebar.selectbox(
74
+ "Choisir un jeu de données",
75
+ seaborn_datasets
76
+ )
77
+
78
+ try:
79
+ df = sns.load_dataset(selected_dataset)
80
+ st.sidebar.success(f"✅ Jeu '{selected_dataset}' chargé")
81
+ except Exception as e:
82
+ st.sidebar.error(f"Erreur : {e}")
83
+
84
+ else:
85
+ # Import de fichier
86
+ uploaded_file = st.sidebar.file_uploader(
87
+ "Importer un fichier CSV",
88
+ type=['csv']
89
+ )
90
+
91
+ if uploaded_file is not None:
92
+ try:
93
+ # Détection automatique du séparateur avec engine='python'
94
+ df = pd.read_csv(uploaded_file, sep=None, engine='python')
95
+ st.sidebar.success("✅ Fichier importé")
96
+ except Exception as e:
97
+ st.sidebar.error(f"Erreur : {e}")
98
+
99
+ # Traitement des données
100
+ if df is not None:
101
+ # Sélection des colonnes catégorielles
102
+ categorical_cols = df.select_dtypes(include=['object', 'category', 'bool']).columns.tolist()
103
+
104
+ # Ajouter les colonnes numériques avec peu de valeurs uniques
105
+ numeric_cols = df.select_dtypes(include=['int64', 'float64']).columns
106
+ for col in numeric_cols:
107
+ if df[col].nunique() <= 10:
108
+ categorical_cols.append(col)
109
+
110
+ if len(categorical_cols) == 0:
111
+ st.warning("⚠️ Aucune variable catégorielle détectée.")
112
+ else:
113
+ st.sidebar.write(f"**{len(categorical_cols)}** variables détectées")
114
+
115
+ # Sélection des colonnes à analyser
116
+ selected_cols = st.sidebar.multiselect(
117
+ "Variables à analyser",
118
+ categorical_cols,
119
+ default=categorical_cols[:min(6, len(categorical_cols))]
120
+ )
121
+
122
+ if len(selected_cols) < 2:
123
+ st.info("ℹ️ Veuillez sélectionner au moins 2 variables.")
124
+ else:
125
+ # Préparation des données
126
+ df_cat = df[selected_cols].copy()
127
+
128
+ # Options de traitement des valeurs manquantes
129
+ nan_handling = st.sidebar.radio(
130
+ "Valeurs manquantes",
131
+ ["Remplacer par 'Missing'", "Supprimer les lignes"]
132
+ )
133
+
134
+ # Traitement des valeurs manquantes
135
+ if nan_handling == "Remplacer par 'Missing'":
136
+ for col in selected_cols:
137
+ # Convertir d'abord en string pour éviter l'erreur avec les categories
138
+ df_cat[col] = df_cat[col].astype(str)
139
+ df_cat[col] = df_cat[col].replace('nan', 'Missing')
140
+ df_cat[col] = df_cat[col].replace('None', 'Missing')
141
+ df_cat[col] = df_cat[col].astype('category')
142
+ else:
143
+ df_cat = df_cat.dropna()
144
+ # Convertir en category
145
+ for col in selected_cols:
146
+ df_cat[col] = df_cat[col].astype('category')
147
+
148
+ # Calcul de la matrice
149
+ if st.sidebar.button("🔄 Calculer", type="primary"):
150
+ with st.spinner("Calcul en cours..."):
151
+ v_cramer_matrix = calculate_cramer_matrix(df_cat, selected_cols)
152
+
153
+ # Onglets pour organiser l'affichage
154
+ tab1, tab2 = st.tabs(["📊 Visualisation", "📋 Données"])
155
+
156
+ with tab1:
157
+ col1, col2 = st.columns([2.5, 1])
158
+
159
+ with col1:
160
+ # Création de la heatmap (taille réduite)
161
+ fig, ax = plt.subplots(figsize=(8, 6))
162
+ sns.heatmap(
163
+ v_cramer_matrix,
164
+ annot=True,
165
+ cmap='coolwarm',
166
+ fmt=".2f",
167
+ linewidths=0.5,
168
+ cbar_kws={'label': 'V de Cramer'},
169
+ ax=ax,
170
+ vmin=0,
171
+ vmax=1
172
+ )
173
+ plt.title('Matrice des V de Cramer', fontsize=12, pad=15)
174
+ plt.tight_layout()
175
+ st.pyplot(fig)
176
+
177
+ with col2:
178
+ st.markdown("**Interprétation :**")
179
+ st.markdown("""
180
+ - **0.0-0.1** : Très faible
181
+ - **0.1-0.3** : Faible
182
+ - **0.3-0.5** : Modérée
183
+ - **0.5-0.7** : Forte
184
+ - **0.7-1.0** : Très forte
185
+ """)
186
+
187
+ st.markdown("**Top 5 associations :**")
188
+
189
+ # Extraire les valeurs uniques (triangle supérieur)
190
+ associations = []
191
+ for i, col1_name in enumerate(selected_cols):
192
+ for j, col2_name in enumerate(selected_cols):
193
+ if i < j:
194
+ associations.append({
195
+ 'Var 1': col1_name,
196
+ 'Var 2': col2_name,
197
+ 'V': v_cramer_matrix.loc[col1_name, col2_name]
198
+ })
199
+
200
+ if associations:
201
+ top_assoc = pd.DataFrame(associations).sort_values(
202
+ 'V', ascending=False
203
+ ).head(5)
204
+ st.dataframe(top_assoc, hide_index=True, height=210)
205
+
206
+ with tab2:
207
+ st.write(f"**Dimensions :** {df.shape[0]} lignes × {df.shape[1]} colonnes")
208
+ st.dataframe(df.head(20), use_container_width=True)
209
+
210
+ else:
211
+ st.info("👈 Veuillez sélectionner ou importer un jeu de données.")
212
+
213
+ # Footer
214
+ st.markdown("---")
215
+ st.markdown("""
216
+ <div style='text-align: center; color: gray;'>
217
+ <small>Le V de Cramer mesure l'association entre deux variables catégorielles (0 = aucune association, 1 = association parfaite)</small>
218
+ </div>
219
  """, unsafe_allow_html=True)