# app.py import gradio as gr import joblib import pandas as pd import numpy as np import os from sklearn.preprocessing import StandardScaler, OneHotEncoder from sklearn.impute import SimpleImputer from sklearn.compose import ColumnTransformer from sklearn.pipeline import Pipeline from sklearn.ensemble import RandomForestClassifier # --- CORRECCIÓN: Listas hardcodeadas para la interfaz --- UFC_LOCATIONS = [ 'Las Vegas, NV', 'Rio de Janeiro, Brazil', 'Abu Dhabi, UAE', 'London, England', 'New York, NY', 'Otros' ] # --- 1. Cargar objetos serializados --- model = None preprocessor = None model_columns = [] try: model = joblib.load(os.path.join(os.path.dirname(__file__), 'model.pkl')) preprocessor = joblib.load(os.path.join(os.path.dirname(__file__), 'preprocessor.pkl')) model_columns = joblib.load(os.path.join(os.path.dirname(__file__), 'model_columns.pkl')) except Exception as e: print(f"Error al cargar artefactos: {e}") # --- 2. Función de Predicción (Ganador) --- # Los argumentos de entrada son las estadísticas brutas. def predict_winner(F1_KD, F2_KD, F1_STR, F2_STR, F1_TD, F2_TD, F1_SUB, F2_SUB, Round, F1_acc, F2_acc, KD_diff, STR_diff, TD_diff, SUB_diff, Location, wc_B, wc_C, wc_F, wc_Fl, wc_H, wc_LH, wc_L, wc_M, wc_O, wc_SH, wc_W, wc_WB, wc_WF, wc_WFl, wc_WS): if model is None or preprocessor is None: return "ERROR", "Fallo al cargar modelo. Revisa el log de versiones de Scikit-learn." # 1. Crear el DataFrame de entrada input_data = pd.DataFrame({ 'Fighter_1_KD': [F1_KD], 'Fighter_2_KD': [F2_KD], 'Fighter_1_STR': [F1_STR], 'Fighter_2_STR': [F2_STR], 'Fighter_1_TD': [F1_TD], 'Fighter_2_TD': [F2_TD], 'Fighter_1_SUB': [F1_SUB], 'Fighter_2_SUB': [F2_SUB], 'Round': [Round], 'Fighter_1_accuracy': [F1_acc], 'Fighter_2_accuracy': [F2_acc], 'KD_diff': [KD_diff], 'STR_diff': [STR_diff], 'TD_diff': [TD_diff], 'SUB_diff': [SUB_diff], 'Location': [Location], 'weight_class_Bantamweight': [wc_B], 'weight_class_Catch Weight': [wc_C], 'weight_class_Featherweight': [wc_F], 'weight_class_Flyweight': [wc_Fl], 'weight_class_Heavyweight': [wc_H], 'weight_class_Light Heavyweight': [wc_LH], 'weight_class_Lightweight': [wc_L], 'weight_class_Middleweight': [wc_M], 'weight_class_Open Weight': [wc_O], 'weight_class_Super Heavyweight': [wc_SH], 'weight_class_Welterweight': [wc_W], "weight_class_Women's Bantamweight": [wc_WB], "weight_class_Women's Featherweight": [wc_WF], "weight_class_Women's Flyweight": [wc_WFl], "weight_class_Women's Strawweight": [wc_WS] }) # 2. Preprocesamiento: Utilizar el ColumnTransformer ajustado. X_processed = preprocessor.transform(input_data) X_final = pd.DataFrame(X_processed, columns=model_columns) # 3. Predicción # P(F1 Gana) = P(Clase 1) proba_f1_wins = model.predict_proba(X_final)[0][1] # 4. Formato de Salida if proba_f1_wins >= 0.50: winner = "PELEADOR 1 (Predicción)" confidence_percent = f"{proba_f1_wins*100:.2f}%" else: winner = "PELEADOR 2 (Predicción)" # La confianza es 1 - P(F1 Gana) confidence_percent = f"{(1 - proba_f1_wins)*100:.2f}%" return winner, confidence_percent # --- 3. Creación de la Interfaz Gradio --- inputs = [ gr.Slider(0, 5, value=1, step=1, label="KD P1"), gr.Slider(0, 5, value=0, step=1, label="KD P2"), gr.Slider(0, 300, value=70, label="STR P1"), gr.Slider(0, 300, value=50, label="STR P2"), gr.Slider(0, 20, value=5, label="TD P1"), gr.Slider(0, 20, value=2, label="TD P2"), gr.Slider(0, 5, value=0, step=1, label="SUB P1"), gr.Slider(0, 5, value=0, step=1, label="SUB P2"), gr.Slider(1, 5, value=3, step=1, label="Ronda actual (Round)"), gr.Slider(0, 1, value=0.4, label="Precisión STR P1 (F1_acc)"), gr.Slider(0, 1, value=0.3, label="Precisión STR P2 (F2_acc)"), gr.Slider(-5, 5, value=1, label="Diferencia de KD"), gr.Slider(-300, 300, value=20, label="Diferencia de STR"), gr.Slider(-20, 20, value=3, label="Diferencia de TD"), gr.Slider(-5, 5, value=0, label="Diferencia de SUB"), gr.Dropdown(UFC_LOCATIONS, value='Las Vegas, NV', label="Ubicación"), gr.Checkbox(value=True, label="weight_class_Lightweight (wc_L)"), gr.Checkbox(value=False, label="weight_class_Bantamweight (wc_B)"), gr.Checkbox(value=False, label="weight_class_Catch Weight (wc_C)"), gr.Checkbox(value=False, label="weight_class_Featherweight (wc_F)"), gr.Checkbox(value=False, label="weight_class_Flyweight (wc_Fl)"), gr.Checkbox(value=False, label="weight_class_Heavyweight (wc_H)"), gr.Checkbox(value=False, label="weight_class_Light Heavyweight (wc_LH)"), gr.Checkbox(value=False, label="weight_class_Middleweight (wc_M)"), gr.Checkbox(value=False, label="weight_class_Open Weight (wc_O)"), gr.Checkbox(value=False, label="weight_class_Super Heavyweight (wc_SH)"), gr.Checkbox(value=False, label="weight_class_Welterweight (wc_W)"), gr.Checkbox(value=False, label="weight_class_Women's Bantamweight (wc_WB)"), gr.Checkbox(value=False, label="weight_class_Women's Featherweight (wc_WF)"), gr.Checkbox(value=False, label="weight_class_Women's Flyweight (wc_WFl)"), gr.Checkbox(value=False, label="weight_class_Women's Strawweight (wc_WS)") ] outputs = [gr.Textbox(label="Ganador Predicho"), gr.Textbox(label="Confianza (%)")] gr.Interface( fn=predict_winner, inputs=inputs, outputs=outputs, title="🥊 Predictor del Ganador de Combates UFC", description="Modelo Random Forest para predecir si el Peleador 1 o el Peleador 2 ganará." ).launch(server_name="0.0.0.0", server_port=7860)