KLEB38 commited on
Commit
2f42479
·
1 Parent(s): 060e228

feat:added predict endpoint with Pydantic validation

Browse files
Files changed (3) hide show
  1. app/main.py +79 -6
  2. app/pipeline_rh.joblib +2 -2
  3. app/schemas.py +32 -0
app/main.py CHANGED
@@ -1,24 +1,97 @@
1
  from fastapi import FastAPI
 
2
  import joblib
 
3
 
4
  app = FastAPI() # On crée l'outil (le guichet)
5
 
6
  # Au démarrage, on charge ton pipeline
7
  model = joblib.load('app/pipeline_rh.joblib')
8
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
  @app.get("/") # La page d'accueil de ton API
10
  def read_root():
11
- return {"message": "Bienvenue sur l'API RH de Futurisys"}
12
 
13
  @app.post("/predict")
14
- def predict(data: dict):
15
  # 1. On transforme le dictionnaire reçu en DataFrame pandas
16
- df = pd.DataFrame([data])
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
 
18
  # 2. On utilise le pipeline pour faire la prédiction
19
  prediction = model.predict(df)
20
 
21
- # 3. On renvoie le résultat au format JSON
22
  return {
23
- "statut_employe": int(prediction[0])
24
- }
 
1
  from fastapi import FastAPI
2
+ import pandas as pd
3
  import joblib
4
+ from app.schemas import EmployeeInput
5
 
6
  app = FastAPI() # On crée l'outil (le guichet)
7
 
8
  # Au démarrage, on charge ton pipeline
9
  model = joblib.load('app/pipeline_rh.joblib')
10
 
11
+ def inconsistency(df):
12
+ if df["departement"] == "Commercial":
13
+ if (
14
+ df["domaine_etude"]
15
+ == "Marketing"
16
+ # or df["domaine_etude"] == "Transformation Digitale"
17
+ # or df["domaine_etude"] == "Infra & Cloud"
18
+ # or df["domaine_etude"] == "Entrepreunariat"
19
+ ):
20
+ return 0
21
+ else:
22
+ return 1
23
+
24
+ elif df["departement"] == "Consulting":
25
+ if (
26
+ df["domaine_etude"] == "Infra & Cloud"
27
+ or df["domaine_etude"] == "Transformation Digitale"
28
+ # or df["domaine_etude"] == "Entrepreunariat"
29
+ ):
30
+ return 0
31
+ else:
32
+ return 1
33
+
34
+ elif df["departement"] == "Ressources Humaines":
35
+ if (
36
+ df["domaine_etude"] == "Ressources Humaines"
37
+ or df["domaine_etude"] == "Entrepreunariat"
38
+ ):
39
+ return 0
40
+ else:
41
+ return 1
42
+
43
+ def promotion(df):
44
+ if (
45
+ df["annes_sous_responsable_actuel"] > 4
46
+ and df["annees_depuis_la_derniere_promotion"] > 4
47
+ ):
48
+ return 1
49
+ else:
50
+ return 0
51
+
52
+ def developpement(df):
53
+ if df["annees_dans_l_entreprise"] == 0:
54
+ return 0
55
+ elif df["annees_dans_l_entreprise"] >= 2 and df["nb_formations_suivies"] <= 1:
56
+ return 1
57
+ else:
58
+ return 0
59
+
60
+ def depart(x):
61
+ if x == 0:
62
+ return "The staff has a LOW probability of resigning"
63
+ if x==1:
64
+ return "The staff has a HIGH probability of resigning"
65
+
66
+
67
  @app.get("/") # La page d'accueil de ton API
68
  def read_root():
69
+ return {"message": "Welcome to the FUTURISYS HR predictor API"}
70
 
71
  @app.post("/predict")
72
+ def predict(data: EmployeeInput):
73
  # 1. On transforme le dictionnaire reçu en DataFrame pandas
74
+ df = pd.DataFrame([data.model_dump()])
75
+
76
+ # Encodage binaire non inclus dans le pipeline:
77
+ df['genre']= df["genre"].map({"M": 1, "F": 0})
78
+ df['heure_supplementaires']= df["heure_supplementaires"].map({"Oui": 1, "Non": 0})
79
+
80
+ # Changement de type pour augmentation salaire precedente (non inclus dans pipeline)
81
+ df["augementation_salaire_precedente"] = df["augementation_salaire_precedente"].apply(lambda x: float(x[:-1]) / 100)
82
+ dft = df[[item for item in df.columns if item.startswith("satisfaction")]].copy()
83
+ dft.loc[:, "overall_satisfaction"] = dft.mean(
84
+ axis=1
85
+ )
86
+ df["overall_satisfaction"] = dft["overall_satisfaction"].copy()
87
+ df["expertise_inconcistency"] = df.apply(inconsistency, axis=1)
88
+ df["managarial_stagnation"] = df.apply(promotion, axis=1)
89
+ df["developpement_stagnation"] = df.apply(developpement, axis=1)
90
 
91
  # 2. On utilise le pipeline pour faire la prédiction
92
  prediction = model.predict(df)
93
 
94
+ # 3. On renvoie le résultat au format JSON
95
  return {
96
+ "statut_employe": depart(int(prediction[0]))
97
+ }
app/pipeline_rh.joblib CHANGED
@@ -1,3 +1,3 @@
1
  version https://git-lfs.github.com/spec/v1
2
- oid sha256:d2f9f36f06fd2578a274d7661a710f7c0693dad3ecc83e2c2f80b5ad674852f9
3
- size 197529
 
1
  version https://git-lfs.github.com/spec/v1
2
+ oid sha256:a5e9e643a821334a5580ea7b58e4211a4acce4b7b2c010907cce800f7e711a4e
3
+ size 204942
app/schemas.py CHANGED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel, Field
2
+ from typing import Literal
3
+
4
+
5
+ class EmployeeInput(BaseModel):
6
+ genre: Literal["M", "F"] = Field(..., alias="Genre")
7
+ statut_marital: str = Field(..., alias="Statut Marital")
8
+ departement: str = Field(..., alias="Département")
9
+ poste: str = Field(..., alias="Poste")
10
+ domaine_etude: str = Field(..., alias="Domaine d'étude")
11
+ frequence_deplacement: str = Field(..., alias="Fréquence de déplacement")
12
+ heure_supplementaires: Literal["Oui", "Non"] = Field(..., alias="Heures supplémentaires")
13
+ age: int = Field(..., alias="Âge")
14
+ revenu_mensuel: int = Field(..., alias="Revenu mensuel")
15
+ nombre_experiences_precedentes: int = Field(..., alias="Nombre d'expériences précédentes")
16
+ annee_experience_totale: int = Field(..., alias="Années d'expérience totale")
17
+ annees_dans_l_entreprise: int = Field(..., alias="Années dans l'entreprise")
18
+ annees_dans_le_poste_actuel: int = Field(..., alias="Années dans le poste actuel")
19
+ nb_formations_suivies: int = Field(..., alias="Nombre de formations suivies")
20
+ distance_domicile_travail: int = Field(..., alias="Distance domicile-travail")
21
+ niveau_education: int = Field(..., alias="Niveau d'éducation")
22
+ annees_depuis_la_derniere_promotion: int = Field(..., alias="Années depuis la dernière promotion")
23
+ annes_sous_responsable_actuel: int = Field(..., alias="Années sous responsable actuel")
24
+ satisfaction_employee_environnement: int = Field(..., alias="Satisfaction environnement")
25
+ note_evaluation_precedente: int = Field(..., alias="Note évaluation précédente")
26
+ satisfaction_employee_nature_travail: int = Field(..., alias="Satisfaction nature du travail")
27
+ satisfaction_employee_equipe: int = Field(..., alias="Satisfaction équipe")
28
+ satisfaction_employee_equilibre_pro_perso: int = Field(..., alias="Satisfaction équilibre pro/perso")
29
+ note_evaluation_actuelle: int = Field(..., alias="Note évaluation actuelle")
30
+ augementation_salaire_precedente: str = Field(..., alias="Augmentation salaire précédente")
31
+
32
+ model_config = {"populate_by_name": True}