Spaces:
Runtime error
Runtime error
| import joblib | |
| import pandas as pd | |
| import numpy as np | |
| from flask import Flask, request, jsonify | |
| from flask_cors import CORS | |
| import os | |
| import logging | |
| import threading | |
| import time | |
| from tqdm import tqdm | |
| from tenacity import retry, wait_fixed, stop_after_attempt | |
| from sklearn.preprocessing import StandardScaler, LabelEncoder | |
| from sklearn.impute import SimpleImputer | |
| from sklearn.model_selection import StratifiedKFold | |
| from sklearn.metrics import f1_score, recall_score | |
| from imblearn.over_sampling import SMOTE | |
| from imblearn.under_sampling import RandomUnderSampler | |
| from imblearn.pipeline import Pipeline | |
| from xgboost import XGBClassifier | |
| from lightgbm import LGBMClassifier | |
| from sklearn.ensemble import RandomForestClassifier | |
| from sklearn.linear_model import LogisticRegression | |
| from sklearn.svm import SVC | |
| # Initialiser l'application Flask | |
| app = Flask(__name__) | |
| CORS(app) | |
| # Chemins vers les fichiers de modèle | |
| PRIORITY_MODEL_PATH = 'priority_model.pkl' | |
| SERVICE_MODEL_PATH = 'service_model.pkl' | |
| DATASET_PATH = "my_datasheet_80000.csv" | |
| NEW_DATA_FILE = 'new_data.csv' | |
| MIN_NEW_SAMPLES_FOR_RETRAIN = 100 | |
| # Variables globales pour les modèles | |
| priority_model = None | |
| service_model = None | |
| priority_scaler = None | |
| service_scaler = None | |
| priority_imputer = None | |
| service_imputer = None | |
| label_encoder_service = LabelEncoder() | |
| model_lock = threading.Lock() | |
| # Initialiser le logger | |
| logging.basicConfig(level=logging.INFO) | |
| logger = logging.getLogger(__name__) | |
| # Fonction pour charger les modèles | |
| def load_models(): | |
| global priority_model, service_model, priority_scaler, service_scaler, priority_imputer, service_imputer, label_encoder_service | |
| if os.path.exists(PRIORITY_MODEL_PATH): | |
| priority_model = joblib.load(PRIORITY_MODEL_PATH) | |
| if os.path.exists(SERVICE_MODEL_PATH): | |
| service_model = joblib.load(SERVICE_MODEL_PATH) | |
| priority_scaler = joblib.load('priority_scaler.pkl') | |
| service_scaler = joblib.load('service_scaler.pkl') | |
| priority_imputer = joblib.load('priority_imputer.pkl') | |
| service_imputer = joblib.load('service_imputer.pkl') | |
| label_encoder_service = joblib.load('label_encoder_service.pkl') | |
| # Charger les modèles au démarrage | |
| load_models() | |
| # Fonctions et routes Flask | |
| def predict(): | |
| global priority_model, service_model | |
| if priority_model is None or service_model is None: | |
| load_models() | |
| try: | |
| data = request.get_json() | |
| required_fields = ['age', 'sexe', 'enceinte', 'spo2', 'freq_resp', 'pouls', 'ecg', 'pa', 'temperature', 'imc'] | |
| missing_fields = [field for field in required_fields if field not in data] | |
| if missing_fields: | |
| return jsonify({'error': f'Missing fields: {", ".join(missing_fields)}'}), 400 | |
| input_data = { | |
| 'Age': float(data['age']), | |
| 'Sexe': 0 if data['sexe'].lower() == 'masculin' else 1, | |
| 'Enceinte': 1 if bool(data['enceinte']) else 0, | |
| 'SpO2': float(data['spo2']), | |
| 'Frquce_Rprtr(rpm)': float(data['freq_resp']), | |
| 'Pouls': float(data['pouls']), | |
| 'ECG': 0 if data['ecg'].lower() == 'normal' else 1, | |
| 'PA': float(data['pa']), | |
| 'Temperature': float(data['temperature']), | |
| 'IMC': float(data['imc']), | |
| } | |
| input_df = pd.DataFrame([input_data]) | |
| input_df = enhanced_features(input_df) | |
| suggested_service, suggested_priority = compute_service_and_priority(input_df.iloc[0]) | |
| input_df['Suggested_Priority'] = suggested_priority | |
| with model_lock: | |
| # Priority prediction | |
| priority_input = input_df[PRIORITY_FEATURES] | |
| priority_imputed = priority_imputer.transform(priority_input) | |
| priority_scaled = priority_scaler.transform(priority_imputed) | |
| priority_probs = priority_model.predict_proba(priority_scaled)[0] | |
| priority_pred = np.argmax(priority_probs) + 1 | |
| priority_conf = float(max(priority_probs)) | |
| # Service prediction | |
| service_input = input_df[SERVICE_FEATURES] | |
| service_imputed = service_imputer.transform(service_input) | |
| service_scaled = service_scaler.transform(service_imputed) | |
| service_probs = service_model.predict_proba(service_scaled)[0] | |
| service_pred_idx = np.argmax(service_probs) | |
| service_pred = label_encoder_service.inverse_transform([service_pred_idx])[0] | |
| service_conf = float(max(service_probs)) | |
| # Fallback to rule-based logic if confidence is low or critical conditions apply | |
| if priority_conf < 0.7 or input_df['Critical_Signs'][0] == 1: | |
| priority_pred = suggested_priority | |
| if service_conf < 0.7 or input_df['Enceinte'][0] == 1: | |
| service_pred = suggested_service if input_df['Enceinte'][0] == 0 else 'Gynécologie/Obstétrique' | |
| input_df['Priorite'] = priority_pred | |
| input_df['Service_Suivant'] = service_pred | |
| if not os.path.exists(NEW_DATA_FILE): | |
| input_df.to_csv(NEW_DATA_FILE, index=False) | |
| else: | |
| input_df.to_csv(NEW_DATA_FILE, mode='a', header=False, index=False) | |
| logger.info(f"Predicted: service={service_pred}, priority={priority_pred}, service_conf={service_conf}, priority_conf={priority_conf}") | |
| return jsonify({ | |
| 'priority': int(priority_pred), | |
| 'service_suivant': service_pred, | |
| 'priority_confidence': priority_conf, | |
| 'service_confidence': service_conf | |
| }) | |
| except Exception as e: | |
| logger.error(f"Prediction error: {str(e)}") | |
| return jsonify({'error': str(e)}), 500 | |
| if __name__ == '__main__': | |
| app.run(debug=False, host='0.0.0.0', port=5000) | |