Fernanda7171/RandomForestFeatures
0
1from fastapi import FastAPI, HTTPException2from pydantic import BaseModel3import numpy as np4import pickle5from typing import List6 7app = FastAPI()8 9# Variables globales para el modelo10model = None11threshold = 0.5 12 13def cargar_modelo():14 global model, threshold15 if model is None:16 # Cargamos los archivos que ya tienes en tu Space17 with open("modelo_rf_v4_5feat.pkl", "rb") as f:18 model = pickle.load(f)19 with open("threshold_rf_v4_5feat.pkl", "rb") as f:20 threshold = pickle.load(f)21 22class PredictRequest(BaseModel):23 patient_id: str24 age: float25 activity_level: float26 stress_level: float27 social_support: float28 dia_semana: float29 historial: List[float]30 31@app.get("/health")32def health():33 return {"status": "ok"}34 35@app.post("/predict")36def predict(req: PredictRequest):37 cargar_modelo()38 39 h = np.array(req.historial)40 dia = int(req.dia_semana)41 42 # ── Lógica de Features (idéntica a tu entrenamiento) ──43 if len(h) == 0:44 adh_historica = 0.80; adh_ultimos_3 = 0.80; adh_ultimos_6 = 0.8045 adh_14d = 0.80; estabilidad_14d = 0.0; tendencia_14d = 0.046 ultima_toma = 1; racha_fallos = 0; racha_tomas = 047 max_racha_fallo = 0; n_eventos_previos = 048 else:49 adh_historica = h.mean()50 adh_ultimos_3 = h[-3:].mean() if len(h) >= 3 else h.mean()51 adh_ultimos_6 = h[-6:].mean() if len(h) >= 6 else h.mean()52 ventana_14 = h[-14:]53 adh_14d = ventana_14.mean()54 estabilidad_14d = float(np.std(ventana_14)) if len(ventana_14) > 1 else 0.055 tendencia_14d = adh_14d - adh_historica56 ultima_toma = int(h[-1])57 n_eventos_previos = len(h)58 59 # Cálculo de rachas60 racha_fallos = 061 for t in reversed(h):62 if t == 0: racha_fallos += 163 else: break64 racha_tomas = 065 for t in reversed(h):66 if t == 1: racha_tomas += 167 else: break68 69 max_racha_fallo = cf = 070 for t in h:71 if t == 0:72 cf += 173 max_racha_fallo = max(max_racha_fallo, cf)74 else:75 cf = 076 77 # ── Construcción del Vector (17 features) ──78 features = np.array([[79 req.age, req.activity_level, req.stress_level, req.social_support,80 dia, int(dia in [5, 6]), adh_historica, n_eventos_previos,81 adh_ultimos_3, adh_ultimos_6, ultima_toma, racha_fallos,82 racha_tomas, max_racha_fallo, adh_14d, estabilidad_14d, tendencia_14d83 ]], dtype=np.float32)84 85 # Predicción86 prob = float(model.predict_proba(features)[0][1])87 88 # IMPORTANTE: Convertir tipos de NumPy a nativos de Python para el JSON89 return {90 "patient_id": req.patient_id,91 "prob": round(prob, 4),92 "will_take": bool(prob >= threshold), # Corregido: bool nativo93 "risk": "low" if prob >= threshold else "high",94 "threshold": float(round(threshold, 4)) # Corregido: float nativo95 }