Djohell commited on
Commit
96e1f6f
·
verified ·
1 Parent(s): 9a3a19d

Upload processing.py

Browse files
Files changed (1) hide show
  1. processing.py +44 -30
processing.py CHANGED
@@ -2,31 +2,38 @@ import pandas as pd
2
  import numpy as np
3
  import xgboost as xgb
4
  import json
 
 
5
 
6
- # --- 1. DICTIONNAIRE DE MAPPING DIVISION (2 chiffres) -> SECTION (Ton Modèle) ---
7
- # Ce dictionnaire permet à l'utilisateur de saisir "56" et au modèle de recevoir "Hébergement et restauration"
8
- NAF_TO_SECTION = {
9
- "01": "Agriculture, sylviculture et pêche", "02": "Agriculture, sylviculture et pêche", "03": "Agriculture, sylviculture et pêche",
10
- "10": "Industrie manufacturière", "11": "Industrie manufacturière", "12": "Industrie manufacturière",
11
- "41": "Construction", "42": "Construction", "43": "Travaux de construction spécialisés",
12
- "45": "Commerce", "46": "Commerce", "47": "Commerce de détail, à l’exception des automobi...",
13
- "49": "Transports et entreposage", "55": "Hébergement et restauration", "56": "Hébergement et restauration",
14
- "58": "Information et communication", "61": "Information et communication",
15
- "64": "Activités financières et d'assurance", "66": "Activités auxiliaires de services financiers e...",
16
- "68": "Activités immobilières",
17
- "69": "Activités juridiques, comptables, de gestion, d'études de conseil",
18
- "71": "Activités d'architecture et d'ingénierie",
19
- "85": "Enseignement",
20
- "86": "Santé humaine et action sociale",
21
- "96": "Autres services personnels"
22
- }
23
 
24
- # Chargement des colonnes exactes du modèle
25
- with open('models/features_config.json', 'r') as f:
26
- FEATURES = json.load(f)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
27
 
28
  def get_sigma(model):
29
- """Extrait le paramètre scale (sigma) du JSON du modèle XGBoost"""
30
  config = json.loads(model.save_config())
31
  def find_key(obj, key):
32
  if isinstance(obj, dict):
@@ -43,31 +50,38 @@ def get_sigma(model):
43
  return float(scale) if scale else 0.8
44
 
45
  def calculate_survival_risk(mu, horizon, s):
46
- """Formule de survie pour distribution Logistique (AFT)"""
47
  z = (np.log(horizon) - mu) / s
48
  z = np.clip(z, -50, 50)
49
  return round((1 / (1 + np.exp(-z))) * 100, 2)
50
 
51
  def map_statut_expert(p2):
52
- """Traduction de la probabilité à 2 ans en libellé métier"""
53
  if p2 > 20: return '🔴 CRITIQUE'
54
  if p2 > 10: return '🟠 VIGILANCE'
55
  if p2 > 5: return '🟡 OBSERVATION'
56
  return '🟢 SAIN'
57
 
 
 
58
  def prepare_input(data):
59
- """Prépare le DMatrix avec mapping automatique des codes APE et CJ"""
60
  df = pd.DataFrame(0.0, index=[0], columns=FEATURES)
61
 
62
  # 1. Variables numériques directes
63
- df['age_au_diagnostic'] = float(data.get('age_estime', 0))
 
 
 
64
  df['Tranche_effectif_num'] = float(data.get('Tranche_effectif_num', 0))
65
- df['risque_departemental'] = float(data.get('code_departement', 0))
66
  df['is_ess'] = int(data.get('is_ess', 0))
67
 
68
- # 2. Mapping APE (Division -> Section)
69
- code_ape_2 = str(data.get('code_ape', ''))[:2]
70
- section_name = NAF_TO_SECTION.get(code_ape_2)
 
 
 
 
 
71
 
72
  if section_name:
73
  col_ape = f"APE_{section_name}"
@@ -76,7 +90,7 @@ def prepare_input(data):
76
  elif 'APE_Autres_Secteurs' in df.columns:
77
  df['APE_Autres_Secteurs'] = 1.0
78
 
79
- # 3. Mapping Catégorie Juridique (CJ_Prefix)
80
  cj_prefix = str(data.get('categorie_juridique', ''))[:4]
81
  col_cj = f"CJ_{cj_prefix}"
82
  if col_cj in df.columns:
 
2
  import numpy as np
3
  import xgboost as xgb
4
  import json
5
+ import os
6
+ import boto3
7
 
8
+ # --- 1. CHARGEMENT DES CONFIGURATIONS (S3 & SECRETS) ---
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
9
 
10
+ # On charge la liste des colonnes depuis le Secret Hugging Face
11
+ FEATURES = json.loads(os.getenv("MODEL_FEATURES", "[]"))
12
+
13
+ def load_from_s3(file_name):
14
+ """Charge un dictionnaire JSON depuis S3"""
15
+ try:
16
+ s3 = boto3.client(
17
+ 's3',
18
+ aws_access_key_id=os.getenv("AWS_ACCESS_KEY_ID"),
19
+ aws_secret_access_key=os.getenv("AWS_SECRET_ACCESS_KEY"),
20
+ region_name=os.getenv("AWS_REGION")
21
+ )
22
+ # Remplace 'NOM_DE_TON_DOSSIER' par le nom du dossier dans ton bucket
23
+ key = f"projet-economie/{file_name}"
24
+ response = s3.get_object(Bucket=os.getenv("AWS_BUCKET_NAME"), Key=key)
25
+ return json.loads(response['Body'].read().decode('utf-8'))
26
+ except Exception as e:
27
+ print(f"⚠️ Erreur S3 sur {file_name}: {e}")
28
+ return {}
29
+
30
+ # On remplace tes dictionnaires en dur par les versions complètes de S3
31
+ DEP_RISK_MAP = load_from_s3("mapping_dep_risk.json")
32
+ APE_SECTION_MAP = load_from_s3("mapping_ape_section.json")
33
+
34
+ # --- 2. FONCTIONS DE CALCUL (Inchangées, elles sont très bien) ---
35
 
36
  def get_sigma(model):
 
37
  config = json.loads(model.save_config())
38
  def find_key(obj, key):
39
  if isinstance(obj, dict):
 
50
  return float(scale) if scale else 0.8
51
 
52
  def calculate_survival_risk(mu, horizon, s):
 
53
  z = (np.log(horizon) - mu) / s
54
  z = np.clip(z, -50, 50)
55
  return round((1 / (1 + np.exp(-z))) * 100, 2)
56
 
57
  def map_statut_expert(p2):
 
58
  if p2 > 20: return '🔴 CRITIQUE'
59
  if p2 > 10: return '🟠 VIGILANCE'
60
  if p2 > 5: return '🟡 OBSERVATION'
61
  return '🟢 SAIN'
62
 
63
+ # --- 3. PRÉPARATION DES DONNÉES (La version robuste) ---
64
+
65
  def prepare_input(data):
66
+ # On crée le DataFrame avec les colonnes exactes du modèle
67
  df = pd.DataFrame(0.0, index=[0], columns=FEATURES)
68
 
69
  # 1. Variables numériques directes
70
+ # Attention au nom de la colonne âge : doit être identique à ton secret FEATURES
71
+ col_age = 'age_au_diagnostic' if 'age_au_diagnostic' in FEATURES else 'age_estime'
72
+ df[col_age] = float(data.get('age_estime', 0))
73
+
74
  df['Tranche_effectif_num'] = float(data.get('Tranche_effectif_num', 0))
 
75
  df['is_ess'] = int(data.get('is_ess', 0))
76
 
77
+ # 2. GESTION DU DÉPARTEMENT (Sauvetage de la Corse)
78
+ code_dep = str(data.get('code_departement', '')).strip().upper()
79
+ # On cherche la valeur dans le mapping S3, sinon 0.05 par défaut
80
+ df['risque_departemental'] = float(DEP_RISK_MAP.get(code_dep, 0.05))
81
+
82
+ # 3. Mapping APE (Via S3)
83
+ code_ape = str(data.get('code_ape', '')).zfill(2)
84
+ section_name = APE_SECTION_MAP.get(code_ape)
85
 
86
  if section_name:
87
  col_ape = f"APE_{section_name}"
 
90
  elif 'APE_Autres_Secteurs' in df.columns:
91
  df['APE_Autres_Secteurs'] = 1.0
92
 
93
+ # 4. Mapping Catégorie Juridique
94
  cj_prefix = str(data.get('categorie_juridique', ''))[:4]
95
  col_cj = f"CJ_{cj_prefix}"
96
  if col_cj in df.columns: