autonomie / bayesian_network_interface.py
l0d0v1c's picture
Upload 9 files
7b0f77f verified
#!/usr/bin/env python3
"""
Interface pour le réseau bayésien d'évaluation d'autonomie
Utilise pgmpy et pyAgrum pour charger et analyser le réseau BIF
"""
import sys
import os
from typing import Dict, List, Optional, Tuple
import pandas as pd
import numpy as np
# Import des bibliothèques pour les réseaux bayésiens
try:
from pgmpy.readwrite import BIFReader
from pgmpy.inference import VariableElimination
from pgmpy.models import BayesianNetwork
PGMPY_AVAILABLE = True
except ImportError:
PGMPY_AVAILABLE = False
print("Warning: pgmpy not installed. Some features will be limited.")
try:
import pyAgrum as gum
PYAGRUM_AVAILABLE = True
except ImportError:
PYAGRUM_AVAILABLE = False
print("Warning: pyAgrum not installed. Some features will be limited.")
# Pour l'interface graphique
try:
import streamlit as st
import plotly.graph_objects as go
import plotly.express as px
STREAMLIT_AVAILABLE = True
except ImportError:
STREAMLIT_AVAILABLE = False
class AutonomyBayesianNetwork:
"""Classe principale pour gérer le réseau bayésien d'autonomie"""
def __init__(self, bif_file: str = "autonomy_functional_complete.bif"):
self.bif_file = bif_file
self.pgmpy_model = None
self.pyagrum_model = None
self.inference_engine = None
# Variables catégorisées (réseau complet fonctionnel - 12 variables)
self.non_actionable_vars = ['Age', 'Sex', 'Education_Level']
self.actionable_vars = ['Physical_Activity', 'BMI_Category', 'Smoking_Status', 'Social_Support', 'Social_Engagement']
self.intermediate_vars = ['Physical_Frailty', 'Cognitive_Function', 'Depression']
self.outcome_vars = ['Global_Autonomy']
self.load_network()
def load_network(self):
"""Charge le réseau depuis le fichier BIF"""
# Debug: Vérifier l'environnement
debug_messages = []
debug_messages.append(f"🔍 Debug - Chargement réseau:")
debug_messages.append(f" - Fichier BIF: {self.bif_file}")
debug_messages.append(f" - Répertoire courant: {os.getcwd()}")
debug_messages.append(f" - Fichier existe: {os.path.exists(self.bif_file)}")
debug_messages.append(f" - pgmpy disponible: {PGMPY_AVAILABLE}")
debug_messages.append(f" - pyagrum disponible: {PYAGRUM_AVAILABLE}")
if os.path.exists(self.bif_file):
try:
with open(self.bif_file, 'r') as f:
content_preview = f.read(200)
debug_messages.append(f" - Aperçu fichier: {content_preview[:100]}...")
except Exception as e:
debug_messages.append(f" - Erreur lecture fichier: {e}")
else:
debug_messages.append(f" - ❌ Fichier {self.bif_file} non trouvé!")
# Sauvegarder les messages de debug pour Streamlit
self.debug_messages = debug_messages
# Aussi les imprimer
for msg in debug_messages:
print(msg)
if PGMPY_AVAILABLE and os.path.exists(self.bif_file):
try:
reader = BIFReader(self.bif_file)
self.pgmpy_model = reader.get_model()
self.inference_engine = VariableElimination(self.pgmpy_model)
success_msg = f"✓ Réseau chargé avec pgmpy depuis {self.bif_file}"
nodes_msg = f" - {len(list(self.pgmpy_model.nodes()))} nœuds, {len(list(self.pgmpy_model.edges()))} arcs"
print(success_msg)
print(nodes_msg)
self.debug_messages.extend([success_msg, nodes_msg])
except Exception as e:
error_msg = f"❌ Erreur pgmpy: {e}"
print(error_msg)
self.debug_messages.append(error_msg)
if PYAGRUM_AVAILABLE and os.path.exists(self.bif_file):
try:
self.pyagrum_model = gum.loadBN(self.bif_file)
success_msg = f"✓ Réseau chargé avec pyAgrum depuis {self.bif_file}"
print(success_msg)
self.debug_messages.append(success_msg)
except Exception as e:
error_msg = f"❌ Erreur pyAgrum: {e}"
print(error_msg)
self.debug_messages.append(error_msg)
# Vérification finale
if self.pgmpy_model is None and self.pyagrum_model is None:
final_msg = "❌ Aucun modèle chargé!"
print(final_msg)
self.debug_messages.append(final_msg)
# Suggestions de diagnostic
if not PGMPY_AVAILABLE:
suggestion = "💡 pgmpy non disponible - vérifiez requirements.txt et installation"
print(suggestion)
self.debug_messages.append(suggestion)
if not PYAGRUM_AVAILABLE:
suggestion = "💡 pyAgrum non disponible - installation optionnelle"
print(suggestion)
self.debug_messages.append(suggestion)
def get_network_structure(self) -> Dict:
"""Retourne la structure du réseau"""
structure = {
'nodes': [],
'edges': [],
'categories': {}
}
# Prioriser pgmpy_model car il est plus fiable
if self.pgmpy_model:
for node in self.pgmpy_model.nodes():
category = self._get_variable_category(node)
structure['nodes'].append({
'name': node,
'category': category
})
structure['categories'][node] = category
structure['edges'] = list(self.pgmpy_model.edges())
elif self.pyagrum_model and PYAGRUM_AVAILABLE:
for node in self.pyagrum_model.names():
category = self._get_variable_category(node)
structure['nodes'].append({
'name': node,
'category': category,
'domain': list(self.pyagrum_model.variable(node).labels())
})
structure['categories'][node] = category
for arc in self.pyagrum_model.arcs():
parent = self.pyagrum_model.variable(arc[0]).name()
child = self.pyagrum_model.variable(arc[1]).name()
structure['edges'].append((parent, child))
return structure
def _get_variable_category(self, var_name: str) -> str:
"""Détermine la catégorie d'une variable"""
if var_name in self.non_actionable_vars:
return 'non_actionable'
elif var_name in self.actionable_vars:
return 'actionable'
elif var_name in self.intermediate_vars:
return 'intermediate'
elif var_name in self.outcome_vars:
return 'outcome'
else:
return 'unknown'
def perform_inference_pgmpy(self, evidence: Dict, query_vars: List[str]) -> pd.DataFrame:
"""Effectue l'inférence avec pgmpy"""
if not self.inference_engine:
return pd.DataFrame()
try:
result = self.inference_engine.query(variables=query_vars, evidence=evidence)
# Convertir en DataFrame
data = []
for var in query_vars:
if hasattr(result, 'values'):
# Si c'est un seul facteur
probs = result.values
if var in result.variables:
var_idx = result.variables.index(var)
states = result.state_names[var]
if len(result.variables) == 1:
# Cas simple: une seule variable
for i, state in enumerate(states):
data.append({
'Variable': var,
'State': state,
'Probability': probs[i]
})
else:
# Cas multiple: marginaliser
marg_factor = result.marginalize([v for v in result.variables if v != var], inplace=False)
for i, state in enumerate(states):
data.append({
'Variable': var,
'State': state,
'Probability': marg_factor.values[i]
})
return pd.DataFrame(data)
except Exception as e:
print(f"Erreur d'inférence pgmpy: {e}")
return pd.DataFrame()
def perform_inference_pyagrum(self, evidence: Dict, query_vars: List[str]) -> pd.DataFrame:
"""Effectue l'inférence avec pyAgrum ou pgmpy en fallback"""
# Essayer d'abord pyAgrum
if self.pyagrum_model and PYAGRUM_AVAILABLE:
try:
ie = gum.LazyPropagation(self.pyagrum_model)
# Définir l'évidence
for var, value in evidence.items():
if var in self.pyagrum_model.names():
var_idx = self.pyagrum_model.idFromName(var)
labels = self.pyagrum_model.variable(var_idx).labels()
if value in labels:
ie.setEvidence({var: value})
ie.makeInference()
# Collecter les résultats
data = []
for var in query_vars:
if var in self.pyagrum_model.names():
posterior = ie.posterior(var)
var_idx = self.pyagrum_model.idFromName(var)
labels = self.pyagrum_model.variable(var_idx).labels()
for i, label in enumerate(labels):
data.append({
'Variable': var,
'State': label,
'Probability': posterior[i]
})
return pd.DataFrame(data)
except Exception as e:
print(f"Erreur d'inférence pyAgrum: {e}")
# Fallback vers pgmpy
if self.inference_engine:
return self.perform_inference_pgmpy(evidence, query_vars)
return pd.DataFrame()
def analyze_intervention(self, intervention: Dict, target: str = 'Global_Autonomy') -> Dict:
"""Analyse l'impact d'une intervention sur l'autonomie"""
results = {
'baseline': None,
'intervention': None,
'improvement': None
}
# Calcul baseline (sans intervention)
baseline = self.perform_inference_pgmpy({}, [target])
if not baseline.empty:
results['baseline'] = baseline
# Calcul avec intervention
intervention_result = self.perform_inference_pgmpy(intervention, [target])
if not intervention_result.empty:
results['intervention'] = intervention_result
# Calculer l'amélioration
if results['baseline'] is not None and results['intervention'] is not None:
baseline_autonomous = results['baseline'][
results['baseline']['State'] == 'autonomous']['Probability'].values
intervention_autonomous = results['intervention'][
results['intervention']['State'] == 'autonomous']['Probability'].values
if len(baseline_autonomous) > 0 and len(intervention_autonomous) > 0:
results['improvement'] = {
'absolute': intervention_autonomous[0] - baseline_autonomous[0],
'relative': ((intervention_autonomous[0] - baseline_autonomous[0]) /
baseline_autonomous[0] * 100)
}
return results
def get_most_influential_factors(self, target: str = 'Global_Autonomy',
n_top: int = 5) -> List[Tuple[str, float]]:
"""Identifie les facteurs les plus influents sur une variable cible"""
influences = []
# Variables et leurs valeurs possibles (adaptées au réseau complet)
variable_states = {
'Physical_Activity': ['sedentary', 'low', 'moderate', 'high'],
'BMI_Category': ['underweight_normal', 'overweight', 'obese_mild', 'obese_severe'],
'Smoking_Status': ['never', 'former', 'current'],
'Social_Support': ['poor', 'moderate', 'good'],
'Social_Engagement': ['low', 'moderate', 'high']
}
if self.inference_engine:
for var in self.actionable_vars:
if var in variable_states:
states = variable_states[var]
if len(states) >= 2:
# Comparer le meilleur et le pire état
best_case = self.perform_inference_pgmpy(
{var: states[-1]}, [target]) # Dernier état (généralement le meilleur)
worst_case = self.perform_inference_pgmpy(
{var: states[0]}, [target]) # Premier état (généralement le pire)
if not best_case.empty and not worst_case.empty:
best_prob = best_case[
best_case['State'] == 'autonomous']['Probability'].values
worst_prob = worst_case[
worst_case['State'] == 'autonomous']['Probability'].values
if len(best_prob) > 0 and len(worst_prob) > 0:
influence = abs(best_prob[0] - worst_prob[0])
influences.append((var, influence))
# Trier par influence décroissante
influences.sort(key=lambda x: x[1], reverse=True)
return influences[:n_top]
def generate_recommendations(self, patient_profile: Dict) -> List[Dict]:
"""Génère des recommandations personnalisées"""
recommendations = []
# Analyser l'état actuel
current_state = self.perform_inference_pgmpy(
patient_profile, ['Global_Autonomy'])
if current_state.empty:
return recommendations
current_autonomy_prob = current_state[
current_state['State'] == 'autonomous']['Probability'].values
if len(current_autonomy_prob) == 0:
return recommendations
current_autonomy_prob = current_autonomy_prob[0]
# Variables et leurs meilleures valeurs
best_states = {
'Physical_Activity': 'high',
'BMI_Category': 'underweight_normal',
'Smoking_Status': 'never',
'Social_Support': 'good',
'Social_Engagement': 'high'
}
# Tester différentes interventions
for var in self.actionable_vars:
if var not in patient_profile and var in best_states:
best_state = best_states[var]
test_profile = patient_profile.copy()
test_profile[var] = best_state
new_state = self.perform_inference_pgmpy(
test_profile, ['Global_Autonomy'])
if not new_state.empty:
new_autonomy_prob = new_state[
new_state['State'] == 'autonomous']['Probability'].values
if len(new_autonomy_prob) > 0:
improvement = new_autonomy_prob[0] - current_autonomy_prob
if improvement > 0.01: # Amélioration significative
# Créer des recommandations personnalisées
rec_text = self._create_recommendation_text(var, best_state)
recommendations.append({
'variable': var,
'recommendation': rec_text,
'expected_improvement': improvement * 100,
'priority': 'high' if improvement > 0.1 else 'medium'
})
# Trier par amélioration attendue
recommendations.sort(key=lambda x: x['expected_improvement'], reverse=True)
return recommendations[:5] # Top 5 recommandations
def _create_recommendation_text(self, variable: str, state: str) -> str:
"""Crée un texte de recommandation personnalisé"""
recommendations = {
'Physical_Activity': {
'high': "Pratiquer une activité physique intense (sport, course) au moins 150 min/semaine"
},
'BMI_Category': {
'underweight_normal': "Maintenir un poids corporel normal (IMC 18.5-24.9)"
},
'Smoking_Status': {
'never': "Éviter complètement le tabagisme ou arrêter de fumer"
},
'Social_Support': {
'good': "Développer un réseau de soutien social fort (famille, amis, communauté)"
},
'Social_Engagement': {
'high': "Participer activement à des activités sociales et communautaires"
}
}
if variable in recommendations and state in recommendations[variable]:
return recommendations[variable][state]
else:
return f"Améliorer {variable} vers {state}"
class BayesianNetworkCLI:
"""Interface en ligne de commande pour le réseau bayésien"""
def __init__(self):
self.network = AutonomyBayesianNetwork()
def run(self):
"""Lance l'interface CLI"""
print("\n" + "="*60)
print("Interface Réseau Bayésien - Évaluation d'Autonomie")
print("="*60)
while True:
print("\nOptions disponibles:")
print("1. Afficher la structure du réseau")
print("2. Effectuer une inférence")
print("3. Analyser une intervention")
print("4. Identifier les facteurs influents")
print("5. Générer des recommandations")
print("6. Quitter")
choice = input("\nVotre choix (1-6): ")
if choice == '1':
self.show_network_structure()
elif choice == '2':
self.perform_inference()
elif choice == '3':
self.analyze_intervention()
elif choice == '4':
self.identify_influential_factors()
elif choice == '5':
self.generate_recommendations()
elif choice == '6':
print("\nAu revoir!")
break
else:
print("Choix invalide. Veuillez réessayer.")
def show_network_structure(self):
"""Affiche la structure du réseau"""
structure = self.network.get_network_structure()
print("\n" + "-"*40)
print("STRUCTURE DU RÉSEAU")
print("-"*40)
print(f"\nNombre de noeuds: {len(structure['nodes'])}")
print(f"Nombre d'arcs: {len(structure['edges'])}")
print("\nVariables par catégorie:")
categories = {}
for node in structure['nodes']:
cat = node['category']
if cat not in categories:
categories[cat] = []
categories[cat].append(node['name'])
for cat, vars in categories.items():
print(f"\n{cat.upper()}:")
for var in vars:
print(f" - {var}")
def perform_inference(self):
"""Effectue une inférence"""
print("\n" + "-"*40)
print("INFÉRENCE BAYÉSIENNE")
print("-"*40)
evidence = {}
print("\nEntrez l'évidence (laissez vide pour terminer):")
while True:
var = input("Variable: ")
if not var:
break
value = input(f"Valeur pour {var}: ")
if value:
evidence[var] = value
query_vars = input("\nVariables à inférer (séparées par virgule): ").split(',')
query_vars = [v.strip() for v in query_vars if v.strip()]
if not query_vars:
query_vars = ['Global_Autonomy']
print(f"\nInférence avec évidence: {evidence}")
print(f"Variables requêtées: {query_vars}")
result = self.network.perform_inference_pgmpy(evidence, query_vars)
if not result.empty:
print("\nRésultats:")
print(result.to_string(index=False))
else:
print("\nAucun résultat disponible.")
def analyze_intervention(self):
"""Analyse une intervention"""
print("\n" + "-"*40)
print("ANALYSE D'INTERVENTION")
print("-"*40)
intervention = {}
print("\nDéfinir l'intervention:")
for var in self.network.actionable_vars:
value = input(f"{var} (laissez vide pour ignorer): ")
if value:
intervention[var] = value
if not intervention:
print("Aucune intervention définie.")
return
print(f"\nAnalyse de l'intervention: {intervention}")
results = self.network.analyze_intervention(intervention)
if results['improvement']:
print(f"\nAmélioration absolue: {results['improvement']['absolute']:.2%}")
print(f"Amélioration relative: {results['improvement']['relative']:.1f}%")
if results['baseline'] is not None:
print("\nÉtat de base:")
print(results['baseline'][results['baseline']['Variable'] == 'Global_Autonomy'].to_string(index=False))
if results['intervention'] is not None:
print("\nAprès intervention:")
print(results['intervention'][results['intervention']['Variable'] == 'Global_Autonomy'].to_string(index=False))
def identify_influential_factors(self):
"""Identifie les facteurs les plus influents"""
print("\n" + "-"*40)
print("FACTEURS INFLUENTS")
print("-"*40)
target = input("\nVariable cible (défaut: Global_Autonomy): ") or 'Global_Autonomy'
n_top = int(input("Nombre de facteurs à afficher (défaut: 5): ") or 5)
factors = self.network.get_most_influential_factors(target, n_top)
if factors:
print(f"\nTop {n_top} facteurs influençant {target}:")
for i, (factor, influence) in enumerate(factors, 1):
print(f"{i}. {factor}: {influence:.2%} d'influence")
else:
print("Aucun facteur influent trouvé.")
def generate_recommendations(self):
"""Génère des recommandations personnalisées"""
print("\n" + "-"*40)
print("RECOMMANDATIONS PERSONNALISÉES")
print("-"*40)
profile = {}
print("\nProfil du patient:")
# Variables non-actionnables essentielles
age = input("Age (age_60_69/age_70_79/age_80_89/age_90_plus): ")
if age:
profile['Age'] = age
sex = input("Sexe (male/female): ")
if sex:
profile['Sex'] = sex
# Variables actionnables actuelles
print("\nÉtat actuel (laissez vide si inconnu):")
for var in ['Physical_Activity', 'BMI_Category', 'Smoking_Status']:
value = input(f"{var}: ")
if value:
profile[var] = value
if not profile:
print("Profil insuffisant pour générer des recommandations.")
return
print(f"\nGénération de recommandations pour: {profile}")
recommendations = self.network.generate_recommendations(profile)
if recommendations:
print("\nRecommandations prioritaires:")
for i, rec in enumerate(recommendations, 1):
print(f"\n{i}. {rec['recommendation']}")
print(f" Amélioration attendue: +{rec['expected_improvement']:.1f}%")
print(f" Priorité: {rec['priority']}")
else:
print("\nAucune recommandation significative identifiée.")
def create_streamlit_app():
"""Crée une application Streamlit pour l'interface web"""
if not STREAMLIT_AVAILABLE:
print("Streamlit n'est pas installé. Interface web non disponible.")
return
st.set_page_config(
page_title="Réseau Bayésien - Autonomie",
page_icon="🧠",
layout="wide"
)
st.title("🧠 Réseau Bayésien pour l'Évaluation d'Autonomie")
st.markdown("---")
# Initialiser le réseau
if 'network' not in st.session_state:
st.session_state.network = AutonomyBayesianNetwork()
network = st.session_state.network
# Sidebar pour la navigation
st.sidebar.title("Navigation")
page = st.sidebar.selectbox(
"Choisir une page",
["Structure du Réseau", "Inférence", "Analyse d'Intervention",
"Facteurs Influents", "Recommandations"]
)
if page == "Structure du Réseau":
st.header("📊 Structure du Réseau Bayésien")
structure = network.get_network_structure()
col1, col2, col3 = st.columns(3)
with col1:
st.metric("Nombre de noeuds", len(structure['nodes']))
with col2:
st.metric("Nombre d'arcs", len(structure['edges']))
with col3:
st.metric("Variables actionnables", len(network.actionable_vars))
# Afficher les variables par catégorie
st.subheader("Variables par catégorie")
categories = {}
for node in structure['nodes']:
cat = node['category']
if cat not in categories:
categories[cat] = []
categories[cat].append(node['name'])
for cat in ['non_actionable', 'actionable', 'intermediate', 'outcome']:
if cat in categories:
with st.expander(f"{cat.replace('_', ' ').title()} ({len(categories[cat])} variables)"):
for var in categories[cat]:
st.write(f"• {var}")
elif page == "Inférence":
st.header("🔍 Inférence Bayésienne")
col1, col2 = st.columns(2)
with col1:
st.subheader("Évidence")
evidence = {}
# Variables non-actionnables
age = st.selectbox("Age",
["", "age_60_69", "age_70_79", "age_80_89", "age_90_plus"])
if age:
evidence['Age'] = age
sex = st.selectbox("Sexe", ["", "male", "female"])
if sex:
evidence['Sex'] = sex
# Variables actionnables
activity = st.selectbox("Activité Physique",
["", "sedentary", "low", "moderate", "high"])
if activity:
evidence['Physical_Activity'] = activity
bmi = st.selectbox("Catégorie IMC",
["", "underweight", "normal", "overweight",
"obese_class1", "obese_class2"])
if bmi:
evidence['BMI_Category'] = bmi
with col2:
st.subheader("Variables à inférer")
query_vars = st.multiselect(
"Sélectionner les variables",
network.outcome_vars + network.intermediate_vars,
default=['Global_Autonomy']
)
if st.button("Effectuer l'inférence"):
if query_vars:
result = network.perform_inference_pgmpy(evidence, query_vars)
if not result.empty:
st.subheader("Résultats")
for var in query_vars:
var_data = result[result['Variable'] == var]
if not var_data.empty:
fig = px.bar(var_data, x='State', y='Probability',
title=f"Distribution de probabilité pour {var}")
st.plotly_chart(fig)
else:
st.error("Aucun résultat disponible")
elif page == "Analyse d'Intervention":
st.header("💊 Analyse d'Intervention")
st.subheader("Définir l'intervention")
intervention = {}
col1, col2 = st.columns(2)
with col1:
for var in network.actionable_vars[:4]:
value = st.selectbox(f"{var}", ["Non modifié"] +
["Option 1", "Option 2", "Option 3"])
if value != "Non modifié":
intervention[var] = value
with col2:
for var in network.actionable_vars[4:]:
value = st.selectbox(f"{var}", ["Non modifié"] +
["Option 1", "Option 2", "Option 3"])
if value != "Non modifié":
intervention[var] = value
if st.button("Analyser l'intervention"):
if intervention:
results = network.analyze_intervention(intervention)
if results['improvement']:
col1, col2 = st.columns(2)
with col1:
st.metric("Amélioration absolue",
f"{results['improvement']['absolute']:.2%}")
with col2:
st.metric("Amélioration relative",
f"{results['improvement']['relative']:.1f}%")
# Graphique comparatif
if results['baseline'] is not None and results['intervention'] is not None:
baseline_data = results['baseline'][
results['baseline']['Variable'] == 'Global_Autonomy']
intervention_data = results['intervention'][
results['intervention']['Variable'] == 'Global_Autonomy']
comparison = pd.DataFrame({
'State': baseline_data['State'].values,
'Baseline': baseline_data['Probability'].values,
'Intervention': intervention_data['Probability'].values
})
fig = go.Figure()
fig.add_trace(go.Bar(name='Baseline', x=comparison['State'],
y=comparison['Baseline']))
fig.add_trace(go.Bar(name='Intervention', x=comparison['State'],
y=comparison['Intervention']))
fig.update_layout(title="Comparaison Baseline vs Intervention",
barmode='group')
st.plotly_chart(fig)
elif page == "Facteurs Influents":
st.header("📈 Facteurs les Plus Influents")
target = st.selectbox("Variable cible",
network.outcome_vars,
index=network.outcome_vars.index('Global_Autonomy'))
n_top = st.slider("Nombre de facteurs", 3, 10, 5)
if st.button("Identifier les facteurs"):
factors = network.get_most_influential_factors(target, n_top)
if factors:
# Créer un graphique à barres
df_factors = pd.DataFrame(factors, columns=['Facteur', 'Influence'])
df_factors['Influence'] = df_factors['Influence'] * 100
fig = px.bar(df_factors, x='Influence', y='Facteur',
orientation='h',
title=f"Top {n_top} facteurs influençant {target}",
labels={'Influence': 'Influence (%)'})
st.plotly_chart(fig)
# Tableau détaillé
st.subheader("Détails")
for i, (factor, influence) in enumerate(factors, 1):
st.write(f"{i}. **{factor}**: {influence:.2%} d'influence")
elif page == "Recommandations":
st.header("📋 Recommandations Personnalisées")
st.subheader("Profil du Patient")
profile = {}
col1, col2 = st.columns(2)
with col1:
age = st.selectbox("Age",
["age_60_69", "age_70_79", "age_80_89", "age_90_plus"])
profile['Age'] = age
sex = st.selectbox("Sexe", ["male", "female"])
profile['Sex'] = sex
activity = st.selectbox("Activité Physique actuelle",
["sedentary", "low", "moderate", "high"])
profile['Physical_Activity'] = activity
with col2:
bmi = st.selectbox("Catégorie IMC actuelle",
["underweight", "normal", "overweight",
"obese_class1", "obese_class2"])
profile['BMI_Category'] = bmi
smoking = st.selectbox("Statut tabagique",
["never", "former", "current"])
profile['Smoking_Status'] = smoking
if st.button("Générer les recommandations"):
with st.spinner("Analyse en cours..."):
recommendations = network.generate_recommendations(profile)
if recommendations:
st.success("Recommandations générées avec succès!")
for i, rec in enumerate(recommendations, 1):
priority_color = {
'high': '🔴',
'medium': '🟡',
'low': '🟢'
}.get(rec['priority'], '⚪')
with st.container():
col1, col2 = st.columns([3, 1])
with col1:
st.write(f"{priority_color} **{rec['recommendation']}**")
with col2:
st.metric("Amélioration",
f"+{rec['expected_improvement']:.1f}%")
else:
st.info("Aucune recommandation significative identifiée.")
def main():
"""Fonction principale"""
if len(sys.argv) > 1 and sys.argv[1] == 'web':
# Lancer l'interface web
if STREAMLIT_AVAILABLE:
create_streamlit_app()
else:
print("Streamlit n'est pas installé. Installez-le avec: pip install streamlit")
print("Lancement de l'interface CLI à la place...")
cli = BayesianNetworkCLI()
cli.run()
else:
# Lancer l'interface CLI
cli = BayesianNetworkCLI()
cli.run()
if __name__ == "__main__":
main()