KLEB38 commited on
Commit
ec9bbcd
·
1 Parent(s): eae5d41

app file in src folder

Browse files
Files changed (2) hide show
  1. src/streamlit_app.py +141 -38
  2. streamlit_app.py +0 -143
src/streamlit_app.py CHANGED
@@ -1,40 +1,143 @@
1
- import altair as alt
2
- import numpy as np
3
- import pandas as pd
4
  import streamlit as st
 
5
 
6
- """
7
- # Welcome to Streamlit!
8
-
9
- Edit `/streamlit_app.py` to customize this app to your heart's desire :heart:.
10
- If you have any questions, checkout our [documentation](https://docs.streamlit.io) and [community
11
- forums](https://discuss.streamlit.io).
12
-
13
- In the meantime, below is an example of what you can do with just a few lines of code:
14
- """
15
-
16
- num_points = st.slider("Number of points in spiral", 1, 10000, 1100)
17
- num_turns = st.slider("Number of turns in spiral", 1, 300, 31)
18
-
19
- indices = np.linspace(0, 1, num_points)
20
- theta = 2 * np.pi * num_turns * indices
21
- radius = indices
22
-
23
- x = radius * np.cos(theta)
24
- y = radius * np.sin(theta)
25
-
26
- df = pd.DataFrame({
27
- "x": x,
28
- "y": y,
29
- "idx": indices,
30
- "rand": np.random.randn(num_points),
31
- })
32
-
33
- st.altair_chart(alt.Chart(df, height=700, width=700)
34
- .mark_point(filled=True)
35
- .encode(
36
- x=alt.X("x", axis=None),
37
- y=alt.Y("y", axis=None),
38
- color=alt.Color("idx", legend=None, scale=alt.Scale()),
39
- size=alt.Size("rand", legend=None, scale=alt.Scale(range=[1, 150])),
40
- ))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
  import streamlit as st
2
+ import requests
3
 
4
+ API_URL = "https://kleb38-oc-p5.hf.space"
5
+
6
+ st.set_page_config(page_title="FUTURISYS — Prédiction RH", page_icon="👥", layout="wide")
7
+ st.title("👥 FUTURISYS Prédiction de départ RH")
8
+
9
+ tab1, tab2 = st.tabs(["📝 Prédiction manuelle", "🔍 Recherche par ID"])
10
+
11
+ # ─── Fonctions communes ────────────────────────────────────────────────────────
12
+
13
+ def afficher_resultat(data):
14
+ prediction = data["statut_employe"]
15
+ score = data["probability_score"]
16
+ facteurs = data["top_5_factors"]
17
+
18
+ # Couleur selon le risque
19
+ if "HIGH" in prediction:
20
+ st.error(f"🚨 {prediction}")
21
+ else:
22
+ st.success(f"✅ {prediction}")
23
+
24
+ st.metric("Score de probabilité", f"{score * 100:.1f}%")
25
+ st.markdown(f"*Seuil stratégique : {data['model_threshold']} — {data['note']}*")
26
+
27
+ st.subheader("Top 5 facteurs SHAP")
28
+ for rang, (facteur, details) in enumerate(facteurs.items()):
29
+ interpretation = details["interpretation"]
30
+ valeur = details["feature_value"]
31
+ st.markdown(f"**{rang+1}. {facteur}** — {interpretation} *(valeur : {valeur})*")
32
+
33
+ # ─── Onglet 1 : Formulaire manuel ─────────────────────────────────────────────
34
+
35
+ with tab1:
36
+ st.header("Saisir les données d'un employé")
37
+
38
+ col1, col2, col3 = st.columns(3)
39
+
40
+ with col1:
41
+ st.subheader("Informations personnelles")
42
+ genre = st.selectbox("Genre", ["M", "F"])
43
+ age = st.number_input("Âge", min_value=18, max_value=65, value=35)
44
+ statut_marital = st.selectbox("Statut marital", ["Célibataire", "Marié(e)", "Divorcé(e)"])
45
+ niveau_education = st.number_input("Niveau d'éducation", min_value=1, max_value=5, value=3)
46
+ domaine_etude = st.selectbox("Domaine d'étude", [
47
+ "RH", "Marketing", "Infra & Cloud", "Transformation digitale", "Entrepreneuriat"
48
+ ])
49
+ ayant_enfants = st.selectbox("Ayant des enfants", ["Oui", "Non"])
50
+ distance_domicile = st.number_input("Distance domicile-travail (km)", min_value=1, max_value=100, value=10)
51
+ frequence_deplacement = st.selectbox("Fréquence de déplacement", ["Jamais", "Occasionnel", "Fréquent"])
52
+
53
+ with col2:
54
+ st.subheader("Poste et expérience")
55
+ departement = st.selectbox("Département", ["Commercial", "Consulting", "RH"])
56
+ poste = st.selectbox("Poste", [
57
+ "Cadre Commercial", "Consultant", "Directeur RH",
58
+ "Responsable RH", "Représentant Commercial", "Responsable Commercial"
59
+ ])
60
+ revenu_mensuel = st.number_input("Revenu mensuel (€)", min_value=1000, max_value=20000, value=5000)
61
+ heure_supplementaires = st.selectbox("Heures supplémentaires", ["Oui", "Non"])
62
+ nb_experiences = st.number_input("Nombre d'expériences précédentes", min_value=0, max_value=10, value=2)
63
+ annees_experience = st.number_input("Années d'expérience totale", min_value=0, max_value=40, value=10)
64
+ annees_entreprise = st.number_input("Années dans l'entreprise", min_value=0, max_value=40, value=5)
65
+ annees_poste = st.number_input("Années dans le poste actuel", min_value=0, max_value=20, value=3)
66
+ annees_promotion = st.number_input("Années depuis la dernière promotion", min_value=0, max_value=15, value=1)
67
+ annees_manager = st.number_input("Années sous responsable actuel", min_value=0, max_value=20, value=2)
68
+ nb_formations = st.number_input("Nombre de formations suivies", min_value=0, max_value=6, value=2)
69
+ augmentation = st.selectbox("Augmentation salaire précédente", [
70
+ "11%", "12%", "13%", "14%", "15%", "16%", "17%", "18%",
71
+ "19%", "20%", "21%", "22%", "23%", "24%", "25%"
72
+ ])
73
+
74
+ with col3:
75
+ st.subheader("Satisfaction")
76
+ satisfaction_env = st.slider("Satisfaction environnement", 1, 4, 3)
77
+ satisfaction_travail = st.slider("Satisfaction nature du travail", 1, 4, 3)
78
+ satisfaction_equipe = st.slider("Satisfaction équipe", 1, 4, 3)
79
+ satisfaction_equilibre = st.slider("Satisfaction équilibre pro/perso", 1, 4, 3)
80
+ note_eval_prec = st.slider("Note évaluation précédente", 1, 4, 3)
81
+ note_eval_actuelle = st.slider("Note évaluation actuelle", 1, 4, 3)
82
+ niveau_hierarchique = st.number_input("Niveau hiérarchique", min_value=1, max_value=5, value=2)
83
+ nb_participation_pee = st.number_input("Participations PEE", min_value=0, max_value=6, value=3)
84
+ nb_employes_sous_resp = st.number_input("Employés sous responsabilité", min_value=0, max_value=20, value=0)
85
+
86
+ if st.button("🔮 Prédire le risque de départ", type="primary"):
87
+ payload = {
88
+ "Genre": genre,
89
+ "Statut Marital": statut_marital,
90
+ "Département": departement,
91
+ "Poste": poste,
92
+ "Domaine d'étude": domaine_etude,
93
+ "Fréquence de déplacement": frequence_deplacement,
94
+ "Heures supplémentaires": heure_supplementaires,
95
+ "Âge": age,
96
+ "Revenu mensuel": revenu_mensuel,
97
+ "Nombre d'expériences précédentes": nb_experiences,
98
+ "Années d'expérience totale": annees_experience,
99
+ "Années dans l'entreprise": annees_entreprise,
100
+ "Années dans le poste actuel": annees_poste,
101
+ "Nombre de formations suivies": nb_formations,
102
+ "Distance domicile-travail": distance_domicile,
103
+ "Niveau d'éducation": niveau_education,
104
+ "Années depuis la dernière promotion": annees_promotion,
105
+ "Années sous responsable actuel": annees_manager,
106
+ "Satisfaction environnement": satisfaction_env,
107
+ "Note évaluation précédente": note_eval_prec,
108
+ "Satisfaction nature du travail": satisfaction_travail,
109
+ "Satisfaction équipe": satisfaction_equipe,
110
+ "Satisfaction équilibre pro/perso": satisfaction_equilibre,
111
+ "Note évaluation actuelle": note_eval_actuelle,
112
+ "Augmentation salaire précédente": augmentation
113
+ }
114
+
115
+ with st.spinner("Prédiction en cours..."):
116
+ try:
117
+ response = requests.post(f"{API_URL}/predict", json=payload)
118
+ if response.status_code == 200:
119
+ afficher_resultat(response.json())
120
+ else:
121
+ st.error(f"Erreur API : {response.status_code} — {response.json()}")
122
+ except Exception as e:
123
+ st.error(f"Impossible de contacter l'API : {e}")
124
+
125
+ # ─── Onglet 2 : Recherche par ID ──────────────────────────────────────────────
126
+
127
+ with tab2:
128
+ st.header("Rechercher un employé par ID")
129
+
130
+ id_employee = st.number_input("ID Employé", min_value=1, value=1, step=1)
131
+
132
+ if st.button("🔍 Rechercher et prédire", type="primary"):
133
+ with st.spinner("Recherche en cours..."):
134
+ try:
135
+ response = requests.get(f"{API_URL}/predict/{id_employee}")
136
+ if response.status_code == 200:
137
+ afficher_resultat(response.json())
138
+ elif response.status_code == 404:
139
+ st.warning(f"⚠️ {response.json()['detail']}")
140
+ else:
141
+ st.error(f"Erreur API : {response.status_code}")
142
+ except Exception as e:
143
+ st.error(f"Impossible de contacter l'API : {e}")
streamlit_app.py DELETED
@@ -1,143 +0,0 @@
1
- import streamlit as st
2
- import requests
3
-
4
- API_URL = "https://kleb38-oc-p5.hf.space"
5
-
6
- st.set_page_config(page_title="FUTURISYS — Prédiction RH", page_icon="👥", layout="wide")
7
- st.title("👥 FUTURISYS — Prédiction de départ RH")
8
-
9
- tab1, tab2 = st.tabs(["📝 Prédiction manuelle", "🔍 Recherche par ID"])
10
-
11
- # ─── Fonctions communes ────────────────────────────────────────────────────────
12
-
13
- def afficher_resultat(data):
14
- prediction = data["statut_employe"]
15
- score = data["probability_score"]
16
- facteurs = data["top_5_factors"]
17
-
18
- # Couleur selon le risque
19
- if "HIGH" in prediction:
20
- st.error(f"🚨 {prediction}")
21
- else:
22
- st.success(f"✅ {prediction}")
23
-
24
- st.metric("Score de probabilité", f"{score * 100:.1f}%")
25
- st.markdown(f"*Seuil stratégique : {data['model_threshold']} — {data['note']}*")
26
-
27
- st.subheader("Top 5 facteurs SHAP")
28
- for rang, (facteur, details) in enumerate(facteurs.items()):
29
- interpretation = details["interpretation"]
30
- valeur = details["feature_value"]
31
- st.markdown(f"**{rang+1}. {facteur}** — {interpretation} *(valeur : {valeur})*")
32
-
33
- # ─── Onglet 1 : Formulaire manuel ─────────────────────────────────────────────
34
-
35
- with tab1:
36
- st.header("Saisir les données d'un employé")
37
-
38
- col1, col2, col3 = st.columns(3)
39
-
40
- with col1:
41
- st.subheader("Informations personnelles")
42
- genre = st.selectbox("Genre", ["M", "F"])
43
- age = st.number_input("Âge", min_value=18, max_value=65, value=35)
44
- statut_marital = st.selectbox("Statut marital", ["Célibataire", "Marié(e)", "Divorcé(e)"])
45
- niveau_education = st.number_input("Niveau d'éducation", min_value=1, max_value=5, value=3)
46
- domaine_etude = st.selectbox("Domaine d'étude", [
47
- "RH", "Marketing", "Infra & Cloud", "Transformation digitale", "Entrepreneuriat"
48
- ])
49
- ayant_enfants = st.selectbox("Ayant des enfants", ["Oui", "Non"])
50
- distance_domicile = st.number_input("Distance domicile-travail (km)", min_value=1, max_value=100, value=10)
51
- frequence_deplacement = st.selectbox("Fréquence de déplacement", ["Jamais", "Occasionnel", "Fréquent"])
52
-
53
- with col2:
54
- st.subheader("Poste et expérience")
55
- departement = st.selectbox("Département", ["Commercial", "Consulting", "RH"])
56
- poste = st.selectbox("Poste", [
57
- "Cadre Commercial", "Consultant", "Directeur RH",
58
- "Responsable RH", "Représentant Commercial", "Responsable Commercial"
59
- ])
60
- revenu_mensuel = st.number_input("Revenu mensuel (€)", min_value=1000, max_value=20000, value=5000)
61
- heure_supplementaires = st.selectbox("Heures supplémentaires", ["Oui", "Non"])
62
- nb_experiences = st.number_input("Nombre d'expériences précédentes", min_value=0, max_value=10, value=2)
63
- annees_experience = st.number_input("Années d'expérience totale", min_value=0, max_value=40, value=10)
64
- annees_entreprise = st.number_input("Années dans l'entreprise", min_value=0, max_value=40, value=5)
65
- annees_poste = st.number_input("Années dans le poste actuel", min_value=0, max_value=20, value=3)
66
- annees_promotion = st.number_input("Années depuis la dernière promotion", min_value=0, max_value=15, value=1)
67
- annees_manager = st.number_input("Années sous responsable actuel", min_value=0, max_value=20, value=2)
68
- nb_formations = st.number_input("Nombre de formations suivies", min_value=0, max_value=6, value=2)
69
- augmentation = st.selectbox("Augmentation salaire précédente", [
70
- "11%", "12%", "13%", "14%", "15%", "16%", "17%", "18%",
71
- "19%", "20%", "21%", "22%", "23%", "24%", "25%"
72
- ])
73
-
74
- with col3:
75
- st.subheader("Satisfaction")
76
- satisfaction_env = st.slider("Satisfaction environnement", 1, 4, 3)
77
- satisfaction_travail = st.slider("Satisfaction nature du travail", 1, 4, 3)
78
- satisfaction_equipe = st.slider("Satisfaction équipe", 1, 4, 3)
79
- satisfaction_equilibre = st.slider("Satisfaction équilibre pro/perso", 1, 4, 3)
80
- note_eval_prec = st.slider("Note évaluation précédente", 1, 4, 3)
81
- note_eval_actuelle = st.slider("Note évaluation actuelle", 1, 4, 3)
82
- niveau_hierarchique = st.number_input("Niveau hiérarchique", min_value=1, max_value=5, value=2)
83
- nb_participation_pee = st.number_input("Participations PEE", min_value=0, max_value=6, value=3)
84
- nb_employes_sous_resp = st.number_input("Employés sous responsabilité", min_value=0, max_value=20, value=0)
85
-
86
- if st.button("🔮 Prédire le risque de départ", type="primary"):
87
- payload = {
88
- "Genre": genre,
89
- "Statut Marital": statut_marital,
90
- "Département": departement,
91
- "Poste": poste,
92
- "Domaine d'étude": domaine_etude,
93
- "Fréquence de déplacement": frequence_deplacement,
94
- "Heures supplémentaires": heure_supplementaires,
95
- "Âge": age,
96
- "Revenu mensuel": revenu_mensuel,
97
- "Nombre d'expériences précédentes": nb_experiences,
98
- "Années d'expérience totale": annees_experience,
99
- "Années dans l'entreprise": annees_entreprise,
100
- "Années dans le poste actuel": annees_poste,
101
- "Nombre de formations suivies": nb_formations,
102
- "Distance domicile-travail": distance_domicile,
103
- "Niveau d'éducation": niveau_education,
104
- "Années depuis la dernière promotion": annees_promotion,
105
- "Années sous responsable actuel": annees_manager,
106
- "Satisfaction environnement": satisfaction_env,
107
- "Note évaluation précédente": note_eval_prec,
108
- "Satisfaction nature du travail": satisfaction_travail,
109
- "Satisfaction équipe": satisfaction_equipe,
110
- "Satisfaction équilibre pro/perso": satisfaction_equilibre,
111
- "Note évaluation actuelle": note_eval_actuelle,
112
- "Augmentation salaire précédente": augmentation
113
- }
114
-
115
- with st.spinner("Prédiction en cours..."):
116
- try:
117
- response = requests.post(f"{API_URL}/predict", json=payload)
118
- if response.status_code == 200:
119
- afficher_resultat(response.json())
120
- else:
121
- st.error(f"Erreur API : {response.status_code} — {response.json()}")
122
- except Exception as e:
123
- st.error(f"Impossible de contacter l'API : {e}")
124
-
125
- # ─── Onglet 2 : Recherche par ID ──────────────────────────────────────────────
126
-
127
- with tab2:
128
- st.header("Rechercher un employé par ID")
129
-
130
- id_employee = st.number_input("ID Employé", min_value=1, value=1, step=1)
131
-
132
- if st.button("🔍 Rechercher et prédire", type="primary"):
133
- with st.spinner("Recherche en cours..."):
134
- try:
135
- response = requests.get(f"{API_URL}/predict/{id_employee}")
136
- if response.status_code == 200:
137
- afficher_resultat(response.json())
138
- elif response.status_code == 404:
139
- st.warning(f"⚠️ {response.json()['detail']}")
140
- else:
141
- st.error(f"Erreur API : {response.status_code}")
142
- except Exception as e:
143
- st.error(f"Impossible de contacter l'API : {e}")