File size: 14,995 Bytes
12f7075 550403f 12f7075 550403f 12f7075 550403f 12f7075 550403f 12f7075 550403f 12f7075 550403f 12f7075 ac4d73c 12f7075 ac4d73c 6e650f2 5588725 ac4d73c 6e650f2 ac4d73c 6e650f2 ac4d73c 6e650f2 550403f ac4d73c 12f7075 ac4d73c 12f7075 ac4d73c 12f7075 ac4d73c 12f7075 550403f |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 |
import streamlit as st
from streamlit_option_menu import option_menu
import pandas as pd
import pickle
import lime
import lime.lime_tabular
import streamlit.components.v1 as components
from PIL import Image
import seaborn as sns
import matplotlib.pyplot as plt
from datetime import datetime
# 1=sidebar menu, 2=horizontal menu, 3=horizontal menu w/ custom menu
EXAMPLE_NO = 3
st.set_page_config(layout='wide')
st.markdown("""
<style>
.block-container {
padding-top: 4rem;
padding-bottom: 0rem;
padding-left: 4rem;
padding-right: 4rem;
}
</style>
""", unsafe_allow_html=True)
def streamlit_menu(example=1):
if example == 1:
# 1. as sidebar menu
with st.sidebar:
selected = option_menu(
menu_title="Main Menu", # required
options=["Acceuil", "Statistique", "Prédiction", "Suivi"], # required
icons=["house", "book", "envelope", "clipboard-data"], # optional
menu_icon="cast", # optional
default_index=0, # optional
)
return selected
if example == 2:
# 2. horizontal menu w/o custom style
selected = option_menu(
menu_title=None, # required
options=["Acceuil", "Statistique", "Prédiction", "Suivi"], # required
icons=["house", "bar-chart", "activity", "clipboard"], # optional
menu_icon="cast", # optional
default_index=0, # optional
orientation="horizontal",
)
return selected
if example == 3:
# 2. horizontal menu with custom style
selected = option_menu(
menu_title=None, # required
options=["Acceuil", "Statistique", "Prédiction", "Suivi"], # required
icons=["house", "bar-chart", "activity", "clipboard"], # optional
menu_icon="cast", # optional
default_index=0, # optional
orientation="horizontal",
styles={
"container": {"padding": "0!important", "background-color": "#fafafa"},
"icon": {"color": "orange", "font-size": "25px"},
"nav-link": {
"font-size": "25px",
"text-align": "left",
"margin": "0px",
"--hover-color": "#eee",
},
"nav-link-selected": {"background-color": "skyblue"},
},
)
return selected
selected = streamlit_menu(example=EXAMPLE_NO)
if selected == "Prédiction":
# st.title(f"You have selected {selected}")
# Load your trained model
with open('model.pkl', 'rb') as file:
model = pickle.load(file)
obesity_mapping = {
0: 'Normal',
1: 'Surpoid\Obése'
}
# Define the input features for the user to input
def user_input_features():
age = st.number_input('Age:',min_value=8, max_value=19, value=19, step=1, format="%d")
classe = st.radio('Classe_', ('Primaire','Secondaire'))
Zone = st.radio('zone', ('Rurale', 'Urbaine'))
Voler = st.radio('Voler', ('Oui', 'Non'))
Diversité = st.radio('Diversité', ('Mauvaise', 'Bonne'))
Region = st.selectbox(
'Region de ',
('Nord_ouest' ,'Sud_ouest', 'Ouest')
)
Source_eau=st.selectbox(
'Provenence ',
('Camwater','Eau_de_surface','forage','Puits','Eau_minérale')
)
Sexe = st.radio('Genre', ('F', 'M'))
Zone = 1 if Zone == 'Rurale' else 0
classe = 1 if classe == 'Primaire' else 0
Diversité = 1 if Diversité == 'Mauvaise' else 0
Region = ['Nord_ouest' ,'Sud_ouest', 'Ouest'].index(Region)
Source_eau=['Camwater','Eau_de_surface','forage','Puits','Eau_minérale'].index(Source_eau)
sex_f = 1 if Sexe == 'F' else 0
sex_m = 1 if Sexe == 'M' else 0
data = {
'Region': Region,
'Zone': Zone,
'Classe': classe,
'Age': age,
'Diversité': Diversité,
'Voler': Voler,
'Source_eau':Source_eau,
'Genre_F': sex_f,
'Genre_M': sex_m
}
features = pd.DataFrame(data, index=[0])
return features
# st.title('Obesity App')
# Display the input fields
input_df = user_input_features()
# Convertir toutes les colonnes non numériques en numérique si possible
input_df = input_df.apply(pd.to_numeric, errors='coerce')
# Remplacer les NaN par une valeur arbitraire (par exemple 0) si nécessaire
input_df = input_df.fillna(0)
# Initialiser LIME
explainer = lime.lime_tabular.LimeTabularExplainer(
training_data=input_df.values, # Entraînement sur la base des données d'entrée
feature_names=input_df.columns,
class_names=[obesity_mapping[0], obesity_mapping[1]],
mode='classification'
)
# Predict button
if st.button('Predict'):
# Make a prediction
prediction = model.predict(input_df)
prediction_proba = model.predict_proba(input_df)[0]
data = {
'Statut nutritionnel': [obesity_mapping[i] for i in range(len(prediction_proba))],
'Probabilité': prediction_proba
}
# Create a dataframe to display the results
result_df = pd.DataFrame(data)
# Transpose the dataframe to have obesity types as columns and add a row header
result_df = result_df.T
result_df.columns = result_df.iloc[0]
result_df = result_df.drop(result_df.index[0])
result_df.index = ['Probability']
# Display the results in a table with proper formatting
st.table(result_df.style.format("{:.4f}"))
# Générer l'explication LIME pour l'individu
# exp = explainer.explain_instance(input_df.values[0], model.predict_proba, num_features=5)
# # Afficher les explications dans Streamlit
# st.subheader('Explication LIME')
# exp.show_in_notebook(show_table=True, show_all=False)
# st.write(exp.as_list())
# Générer l'explication LIME pour l'individu
exp = explainer.explain_instance(input_df.values[0], model.predict_proba, num_features=4)
# Récupérer l'explication LIME sous forme HTML
explanation_html = exp.as_html()
# Afficher l'explication LIME dans Streamlit
st.subheader('Explication LIME')
# Utiliser Streamlit pour afficher du HTML
components.html(explanation_html, height=800) # Ajuster la hauteur selon le contenu
if selected == "Acceuil":
avant_propos = """
<div style="background-color: white; padding: 20px; border-radius: 10px;
display: flex; justify-content: center; align-items: center;
width: 800px; height: auto; margin: auto; flex-direction: column;
box-shadow: 0px 0px 10px rgba(0, 0, 0, 0.1);">
<h2 style="color: blue; text-align: center; font-size: 24px;">Avant-propos</h2>
<p style="color: blue; text-align: center; font-size: 17px;">
L'obésité est l'une des principales préoccupations de santé publique à travers le monde, avec des répercussions notables sur la qualité de vie et les coûts des soins de santé.
Dans un contexte où les maladies chroniques liées à l'obésité, telles que le diabète et les maladies cardiovasculaires, continuent de croître, il est impératif de développer des outils capables de prédire et de prévenir cette condition.
</p>
<p style="color: blue; text-align: center; font-size: 16px;">
L'application que nous présentons ici repose sur les technologies modernes de <strong>machine learning</strong> pour prédire le risque d'obésité à partir de divers facteurs liés au mode de vie,
aux habitudes alimentaires et aux caractéristiques individuelles. Cette solution, développée à l'aide de <strong>Streamlit</strong>, permet non seulement d'offrir une interface intuitive et accessible,
mais également d'analyser rapidement et précisément les données des utilisateurs afin d'anticiper les risques associés au surpoids.
</p>
<p style="color: blue; text-align: center; font-size: 16px;">
L'objectif principal de cette application est de fournir une aide à la décision pour les professionnels de santé, les chercheurs, et même les utilisateurs individuels
qui souhaitent comprendre et gérer leur risque personnel. En quelques clics, les utilisateurs peuvent explorer les facteurs influents et recevoir des prévisions basées sur des algorithmes avancés d'apprentissage automatique.
</p>
<p style="color: blue; text-align: center; font-size: 16px;">
Cette application permet aussi de faire un suivi personnalisé sur l'indice de masse corporelle, precisement de
son statut nutritionnel.
</p>
</div>
"""
# Afficher le texte stylisé en bleu et centré sur un fond blanc
st.markdown(avant_propos, unsafe_allow_html=True)
# Ajouter un bouton qui redirige vers un site externe
url = "https://www.who.int/fr/news-room/fact-sheets/detail/obesity-and-overweight" # Remplacez par l'URL souhaitée
if st.button("pour plus d'informations"):
st.write(f"[Cliquez ici pour visiter le site]({url})")
if selected == "Statistique":
# Ouvrir l'image avec Pillow
#image = Image.open("az.JPEG")
# Redimensionner l'image (largeur, hauteur)
#image = image.resize((300, 200)) # Par exemple, 300x200 pixels
# Afficher l'image redimensionnée
#st.image(image, caption="Image redimensionnée", use_column_width=False)
# Titre de l'application
st.title("Visualisation des données avec Seaborn et Pandas")
# Charger le fichier CSV
uploaded_file = st.file_uploader("Choisissez un fichier", type=["csv", "xlsx", "json"])
if uploaded_file is not None:
# Lecture du fichier CSV
file_extension = uploaded_file.name.split('.')[-1]
if file_extension == 'csv':
# Lecture du fichier CSV
df = pd.read_csv(uploaded_file)
elif file_extension == 'xlsx':
# Lecture du fichier Excel
df = pd.read_excel(uploaded_file)
elif file_extension == 'json':
# Lecture du fichier JSON
df = pd.read_json(uploaded_file)
else:
st.error("Format de fichier non supporté!")
# Afficher le dataframe
st.write("Aperçu du dataset :")
st.write(df.head())
# Afficher les statistiques descriptives
st.write("Statistiques descriptives :")
st.write(df.describe())
# Sélection des variables pour les visualisations
numerical_columns = df.select_dtypes(include=['float64', 'int64']).columns.tolist()
categorical_columns = df.select_dtypes(include=['object', 'category']).columns.tolist()
# Distribution d'une variable
st.subheader("Distribution d'une variable numérique")
selected_column = st.selectbox("Choisissez une variable numérique", numerical_columns)
if st.button("Afficher la distribution"):
fig, ax = plt.subplots(figsize=(5, 6))
sns.histplot(df[selected_column], kde=True, ax=ax)
st.pyplot(fig)
# Scatter plot
st.subheader("Scatter Plot entre deux variables numériques")
x_axis = st.selectbox("Choisissez la variable pour l'axe X", numerical_columns)
y_axis = st.selectbox("Choisissez la variable pour l'axe Y", numerical_columns, key='scatter')
if st.button("Afficher le scatter plot"):
fig, ax = plt.subplots(figsize=(8, 4))
sns.scatterplot(x=df[x_axis], y=df[y_axis], ax=ax)
st.pyplot(fig)
# Boxplot
st.subheader("Boxplot d'une variable numérique par rapport à une variable catégorielle")
selected_categorical = st.selectbox("Choisissez une variable catégorielle", categorical_columns)
selected_numerical = st.selectbox("Choisissez une variable numérique", numerical_columns, key='boxplot')
if st.button("Afficher le boxplot"):
fig, ax = plt.subplots(figsize=(8, 4))
sns.boxplot(x=df[selected_categorical], y=df[selected_numerical], ax=ax)
st.pyplot(fig)
if selected == "Suivi":
# Charger ou initialiser les données de suivi
def load_data():
try:
data = pd.read_csv('imc_data.csv')
except FileNotFoundError:
data = pd.DataFrame(columns=['Date', 'Weight', 'Height', 'BMI', 'Status'])
return data
def save_data(data):
data.to_csv('imc_data.csv', index=False)
# Calculer l'IMC et le statut nutritionnel
def calculate_bmi(weight, height):
return weight / (height ** 2)
def get_nutritional_status(bmi):
if bmi < 18.5:
return "Insuffisance pondérale"
elif 18.5 <= bmi < 25:
return "Poids normal"
elif 25 <= bmi < 30:
return "Surpoids"
else:
return "Obésité"
# Interface utilisateur Streamlit
st.title("Suivi de l'IMC et du Statut Nutritionnel")
# Collecte des données utilisateur
weight = st.number_input("Poids (en kg)", min_value=30.0, max_value=200.0, value=70.0)
height = st.number_input("Taille (en mètres)", min_value=1.0, max_value=2.5, value=1.75)
# Calculer l'IMC et le statut nutritionnel
if height > 0:
bmi = calculate_bmi(weight, height)
status = get_nutritional_status(bmi)
st.write(f"Votre IMC est : {bmi:.2f}")
st.write(f"Statut nutritionnel : {status}")
# Charger et mettre à jour les données de suivi
data = load_data()
if st.button("Enregistrer vos données"):
new_entry = pd.DataFrame({
'Date': [datetime.now().strftime("%Y-%m-%d %H:%M:%S")],
'Weight': [weight],
'Height': [height],
'BMI': [bmi],
'Status': [status]
})
data = pd.concat([data, new_entry], ignore_index=True)
save_data(data)
st.success("Vos données ont été enregistrées avec succès !")
# Afficher l'évolution de l'IMC
if not data.empty:
st.subheader("Évolution de votre IMC")
data['Date'] = pd.to_datetime(data['Date'])
plt.figure(figsize=(10, 6))
plt.plot(data['Date'], data['BMI'], marker='o')
plt.title("Évolution de l'IMC")
plt.xlabel("Date")
plt.ylabel("IMC")
plt.grid(True)
st.pyplot(plt)
# Afficher l'historique des données soumises
st.subheader("Historique des données soumises")
st.dataframe(data[['Date', 'Weight', 'Height', 'BMI', 'Status']])
else:
st.warning("Veuillez entrer une taille valide pour calculer l'IMC.")
|