import logging from fastapi import FastAPI, HTTPException from pydantic import BaseModel import numpy as np import pandas as pd import tensorflow as tf from sklearn.preprocessing import StandardScaler, OneHotEncoder from sklearn.compose import ColumnTransformer # Configurar el logger logging.basicConfig(level=logging.INFO) app = FastAPI() # Cargar el modelo preentrenado desde el archivo .h5 try: model = tf.keras.models.load_model('Model.h5') logging.info("Modelo cargado correctamente.") except Exception as e: logging.error("Error cargando el modelo: %s", e) # Cargar el conjunto de datos para ajuste del preprocesador try: file_path = 'heart.csv' df = pd.read_csv(file_path) logging.info("Conjunto de datos cargado correctamente.") except Exception as e: logging.error("Error cargando el conjunto de datos: %s", e) # Identificar columnas numéricas y categóricas num_features = ['Age', 'RestingBP', 'Cholesterol', 'MaxHR', 'Oldpeak'] cat_features = ['Sex', 'ChestPainType', 'FastingBS', 'RestingECG', 'ExerciseAngina', 'ST_Slope'] # Preprocesamiento: Escalar características numéricas y codificar características categóricas try: preprocessor = ColumnTransformer( transformers=[ ('num', StandardScaler(), num_features), ('cat', OneHotEncoder(handle_unknown='ignore'), cat_features) ]) X = df.drop('HeartDisease', axis=1) preprocessor.fit(X) logging.info("Preprocesador ajustado correctamente.") except Exception as e: logging.error("Error ajustando el preprocesador: %s", e) class HeartDiseaseInput(BaseModel): age: float sex: str chest_pain_type: str resting_bp: float cholesterol: float fasting_bs: int resting_ecg: str max_hr: float exercise_angina: str oldpeak: float st_slope: str @app.get("/") def read_root(): return {"Hello": "World!"} @app.post("/predict") def predict(input: HeartDiseaseInput): try: # Crear un DataFrame con los datos de entrada input_data = pd.DataFrame({ 'Age': [input.age], 'Sex': [input.sex], 'ChestPainType': [input.chest_pain_type], 'RestingBP': [input.resting_bp], 'Cholesterol': [input.cholesterol], 'FastingBS': [input.fasting_bs], 'RestingECG': [input.resting_ecg], 'MaxHR': [input.max_hr], 'ExerciseAngina': [input.exercise_angina], 'Oldpeak': [input.oldpeak], 'ST_Slope': [input.st_slope] }) logging.info("Datos de entrada recibidos: %s", input_data) # Aplicar preprocesamiento input_data_preprocessed = preprocessor.transform(input_data) logging.info("Datos preprocesados: %s", input_data_preprocessed) # Realizar la predicción prediction_prob = model.predict(input_data_preprocessed) predicted_class = (prediction_prob > 0.3).astype(int) logging.info("Probabilidad de predicción: %s", prediction_prob) logging.info("Clase predicha: %s", predicted_class) # Convertir numpy a tipos de datos nativos de Python prediction_prob_python = prediction_prob[0][0].item() predicted_class_python = predicted_class[0][0].item() # Interpretar la predicción result = "Si tiene ataques cardiacos" if predicted_class_python == 1 else "No tiene ataques cardíacos" return {"prediction": result, "probability": prediction_prob_python} except Exception as e: logging.error("Error en la predicción: %s", e) raise HTTPException(status_code=500, detail=str(e))