Spaces:
Sleeping
Sleeping
feat: add database query and prediction diagnostic script
Browse filesAdd scripts/query_db.py with utilities to inspect the database:
- employee count and churn rate stats
- preview of first N employees
- on-demand ML prediction for a given employee id
- logged prediction stats (count, latest entry)
- scripts/query_db.py +80 -0
scripts/query_db.py
ADDED
|
@@ -0,0 +1,80 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
import sys
|
| 2 |
+
import os
|
| 3 |
+
|
| 4 |
+
sys.path.append(os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
|
| 5 |
+
|
| 6 |
+
from dotenv import load_dotenv
|
| 7 |
+
load_dotenv()
|
| 8 |
+
|
| 9 |
+
import pandas as pd
|
| 10 |
+
from app.db.session import SessionLocal
|
| 11 |
+
from app.db.models import Employee, Prediction
|
| 12 |
+
from app.routes.predict import _compute_features
|
| 13 |
+
from ml_model.loader import load_pipeline
|
| 14 |
+
|
| 15 |
+
|
| 16 |
+
def stats_employees(session):
|
| 17 |
+
total = session.query(Employee).count()
|
| 18 |
+
print(f"\n--- Employés en base ---")
|
| 19 |
+
print(f"Total : {total}")
|
| 20 |
+
|
| 21 |
+
quittes = session.query(Employee).filter(Employee.a_quitte_l_entreprise == True).count()
|
| 22 |
+
print(f"Ont quitté : {quittes} ({round(quittes / total * 100, 1)}%)")
|
| 23 |
+
|
| 24 |
+
|
| 25 |
+
def apercu_employees(session, n=5):
|
| 26 |
+
rows = session.query(Employee).limit(n).all()
|
| 27 |
+
print(f"\n--- Aperçu ({n} premiers employés) ---")
|
| 28 |
+
for e in rows:
|
| 29 |
+
print(f" id={e.id} | {e.poste} | {e.statut_marital} | quitte={e.a_quitte_l_entreprise}")
|
| 30 |
+
|
| 31 |
+
|
| 32 |
+
def predict_from_db(session, employee_id: int):
|
| 33 |
+
pipeline, threshold = load_pipeline()
|
| 34 |
+
|
| 35 |
+
emp = session.query(Employee).filter(Employee.id == employee_id).first()
|
| 36 |
+
if not emp:
|
| 37 |
+
print(f"Employé id={employee_id} introuvable.")
|
| 38 |
+
return
|
| 39 |
+
|
| 40 |
+
data = {col: getattr(emp, col) for col in [
|
| 41 |
+
"age", "genre", "statut_marital", "poste", "domaine_etude",
|
| 42 |
+
"niveau_education", "nombre_experiences_precedentes", "annee_experience_totale",
|
| 43 |
+
"annees_dans_l_entreprise", "annees_dans_le_poste_actuel",
|
| 44 |
+
"annees_sous_responsable_actuel", "annees_depuis_la_derniere_promotion",
|
| 45 |
+
"note_evaluation_actuelle", "note_evaluation_precedente",
|
| 46 |
+
"augmentation_salaire_precedente", "nb_formations_suivies",
|
| 47 |
+
"nombre_participation_pee", "satisfaction_employee_environnement",
|
| 48 |
+
"satisfaction_employee_nature_travail", "satisfaction_employee_equipe",
|
| 49 |
+
"satisfaction_employee_equilibre_pro_perso", "heure_supplementaires",
|
| 50 |
+
"frequence_deplacement", "distance_domicile_travail", "revenu_mensuel",
|
| 51 |
+
]}
|
| 52 |
+
|
| 53 |
+
df = _compute_features(pd.DataFrame([data]))
|
| 54 |
+
proba = float(pipeline.predict_proba(df)[0][1])
|
| 55 |
+
prediction = int(proba >= threshold)
|
| 56 |
+
label = "Quitte" if prediction == 1 else "Reste"
|
| 57 |
+
|
| 58 |
+
print(f"\n--- Prédiction pour l'employé id={employee_id} ---")
|
| 59 |
+
print(f" Poste : {emp.poste} | Réel : {'Quitte' if emp.a_quitte_l_entreprise else 'Reste'}")
|
| 60 |
+
print(f" Prédit : {label} (probabilité : {round(proba, 4)})")
|
| 61 |
+
|
| 62 |
+
|
| 63 |
+
def stats_predictions(session):
|
| 64 |
+
total = session.query(Prediction).count()
|
| 65 |
+
print(f"\n--- Prédictions loggées en base ---")
|
| 66 |
+
print(f"Total : {total}")
|
| 67 |
+
if total > 0:
|
| 68 |
+
derniere = session.query(Prediction).order_by(Prediction.id.desc()).first()
|
| 69 |
+
print(f"Dernière : id={derniere.id} | {derniere.label} | proba={derniere.probabilite} | {derniere.created_at}")
|
| 70 |
+
|
| 71 |
+
|
| 72 |
+
if __name__ == "__main__":
|
| 73 |
+
session = SessionLocal()
|
| 74 |
+
try:
|
| 75 |
+
stats_employees(session)
|
| 76 |
+
apercu_employees(session, n=5)
|
| 77 |
+
predict_from_db(session, employee_id=1)
|
| 78 |
+
stats_predictions(session)
|
| 79 |
+
finally:
|
| 80 |
+
session.close()
|