# ========================================================= # Predicción de Supervivencia en el Titanic — Demo Gradio # Pensada para desplegarse en Hugging Face Spaces. # # La interfaz pregunta en "idioma humano" (Sexo, Puerto de # embarque, Clase del pasaje...) y la app traduce internamente # esas respuestas a las columnas one-hot que espera el modelo. # ========================================================= import json import pickle import pandas as pd import gradio as gr # ------------------------------------------------------- # 1. Cargar modelo y archivos auxiliares # ------------------------------------------------------- with open("model_rf.pkl", "rb") as f: model = pickle.load(f) # Orden exacto de columnas usado en el entrenamiento with open("model_columns.json", "r") as f: MODEL_COLUMNS = json.load(f) # Rangos min-max (post-limpieza) para los sliders with open("ranges.json", "r") as f: RANGES = json.load(f) # ------------------------------------------------------- # 2. Función de predicción # ------------------------------------------------------- def predecir(clase, edad, hermanos, padres_hijos, tarifa, sexo, puerto): """Recibe los valores 'humanos' de la interfaz, los traduce a las columnas one-hot del modelo y devuelve las probabilidades.""" # Traducción interfaz → columnas del modelo fila = { "Clase": int(clase[0]), # "1ª clase" → 1 "Edad": edad, "HermanosConyuge": hermanos, "PadresHijos": padres_hijos, "Tarifa": tarifa, "Sexo_mujer": 1 if sexo == "Mujer" else 0, "PuertoEmbarque_Queenstown": 1 if puerto.startswith("Queenstown") else 0, "PuertoEmbarque_Southampton": 1 if puerto.startswith("Southampton") else 0, # Cherbourg es la categoría base (drop_first): ambas dummies en 0 } # Reconstruir el vector en el MISMO orden del entrenamiento x = pd.DataFrame([fila], columns=MODEL_COLUMNS) prob_sobrevive = float(model.predict_proba(x)[0][1]) # gr.Label muestra esto como barras de probabilidad return { "Sobrevive 🟢": prob_sobrevive, "No sobrevive 🔴": 1 - prob_sobrevive, } # ------------------------------------------------------- # 3. Construcción de la interfaz # ------------------------------------------------------- entradas = [ gr.Radio( choices=["1ª clase", "2ª clase", "3ª clase"], value="3ª clase", label="Clase del pasaje", info="1ª = la más cara, 3ª = la más económica", ), gr.Slider( RANGES["Edad"]["min"], RANGES["Edad"]["max"], value=28, step=1, label="Edad (años)", ), gr.Slider( RANGES["HermanosConyuge"]["min"], RANGES["HermanosConyuge"]["max"], value=0, step=1, label="Hermanos/as o cónyuge a bordo", ), gr.Slider( RANGES["PadresHijos"]["min"], RANGES["PadresHijos"]["max"], value=0, step=1, label="Padres o hijos a bordo", ), gr.Slider( RANGES["Tarifa"]["min"], RANGES["Tarifa"]["max"], value=15, step=0.5, label="Tarifa pagada (libras de 1912)", ), gr.Radio( choices=["Mujer", "Hombre"], value="Mujer", label="Sexo", ), gr.Radio( choices=["Cherbourg (Francia)", "Queenstown (Irlanda)", "Southampton (Inglaterra)"], value="Southampton (Inglaterra)", label="Puerto de embarque", ), ] app = gr.Interface( fn=predecir, inputs=entradas, outputs=gr.Label(num_top_classes=2, label="Predicción"), title="🚢 Predicción de Supervivencia en el Titanic", description=( "Modelo **Random Forest** entrenado con el dataset clásico del Titanic. " "Ajusta las características del pasajero y el modelo estimará su " "probabilidad de supervivencia.\n\n" "*Pipeline sin data leakage: imputación, outliers y escalado " "calculados solo con el set de entrenamiento.*" ), examples=[ ["1ª clase", 35, 1, 0, 53.0, "Mujer", "Cherbourg (Francia)"], ["3ª clase", 25, 0, 0, 7.5, "Hombre", "Southampton (Inglaterra)"], ["2ª clase", 8, 1, 2, 26.0, "Hombre", "Southampton (Inglaterra)"], ], flagging_mode="never", ) # ------------------------------------------------------- # 4. Ejecutar la aplicación # ------------------------------------------------------- if __name__ == "__main__": app.launch()