Allisona commited on
Commit
653b543
verified
1 Parent(s): e5b452b

Upload 6 files

Browse files
Files changed (6) hide show
  1. README (1).md +28 -0
  2. app (1).py +96 -0
  3. model.pkl +3 -0
  4. model_columns.pkl +3 -0
  5. preprocessor.pkl +3 -0
  6. requirements (1).txt +6 -0
README (1).md ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # 馃 An谩lisis y Despliegue de Datos UFC (ML Space)
2
+
3
+ Este Hugging Face Space aloja el modelo de Machine Learning desarrollado para el proyecto de An谩lisis de Datos de la asignatura, utilizando Gradio para crear una interfaz de usuario y una API de inferencia.
4
+
5
+ ## 馃幆 Objetivo
6
+ El modelo tiene como objetivo principal predecir la **probabilidad de que un combate de UFC termine por Knockout/Technical Knockout (KO/TKO)**, bas谩ndose en estad铆sticas de los peleadores (golpeo, derribos, precisi贸n) y el contexto de la pelea (categor铆a de peso y ubicaci贸n).
7
+
8
+ ## 馃殌 Arquitectura del Modelo
9
+ * **Problema:** Clasificaci贸n Binaria.
10
+ * **Algoritmo:** **Random Forest Classifier** (Seleccionado por su alto rendimiento en m茅tricas AUC y F1 Score).
11
+ * **Preprocesamiento:**
12
+ * **Escalado:** `StandardScaler` aplicado a todas las estad铆sticas brutas.
13
+ * **Codificaci贸n:** `OneHotEncoder` aplicado a la variable categ贸rica `Location`.
14
+ * **Features:** Se utilizan variables de diferencia (`KD_diff`, `STR_diff`, etc.) y las variables OHE de la categor铆a de peso (`weight_class_...`) como features de entrada.
15
+
16
+ ## 馃捇 Requisitos de la Aplicaci贸n
17
+ * **SDK:** Gradio
18
+ * **Librer铆as:** `scikit-learn`, `pandas`, `numpy`, `joblib`.
19
+
20
+ ## 鈿欙笍 Estructura del Proyecto
21
+ * `app.py`: El c贸digo de la aplicaci贸n Gradio.
22
+ * `requirements.txt`: Dependencias de Python.
23
+ * `model.pkl`: Modelo de clasificaci贸n serializado.
24
+ * `preprocessor.pkl`: El ColumnTransformer ajustado.
25
+ * `model_columns.pkl`: Lista de las columnas de entrada, asegurando la integridad del pipeline.
26
+
27
+ ---
28
+ *Este proyecto demuestra el ciclo de vida completo de un modelo de Machine Learning, desde la limpieza de datos hasta el despliegue en la nube.*
app (1).py ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # app.py
2
+ import gradio as gr
3
+ import joblib
4
+ import pandas as pd
5
+ import numpy as np
6
+ import os
7
+ from sklearn.preprocessing import StandardScaler # Asegura que joblib pueda cargar el objeto
8
+
9
+ # --- 1. Cargar objetos serializados ---
10
+ try:
11
+ # Carga segura de artefactos en el entorno de Hugging Face
12
+ model = joblib.load(os.path.join(os.path.dirname(__file__), 'model.pkl'))
13
+ preprocessor = joblib.load(os.path.join(os.path.dirname(__file__), 'preprocessor.pkl'))
14
+ model_columns = joblib.load(os.path.join(os.path.dirname(__file__), 'model_columns.pkl'))
15
+ except Exception as e:
16
+ # Manejo de error si los archivos no se encuentran o est谩n corruptos
17
+ print(f"Error al cargar artefactos: {e}")
18
+ model = None
19
+ preprocessor = None
20
+ model_columns = []
21
+
22
+ # --- 2. Funci贸n de Predicci贸n (N煤cleo de la API) ---
23
+ # Los argumentos de entrada coinciden con las columnas de X antes del preprocesamiento
24
+ def predict_ko_tko(F1_KD, F2_KD, F1_STR, F2_STR, F1_TD, F2_TD, F1_SUB, F2_SUB, Round,
25
+ F1_acc, F2_acc, KD_diff, STR_diff, TD_diff, SUB_diff, Location,
26
+ # Se incluyen las columnas OHE ya existentes en el CSV como inputs discretos
27
+ wc_B, wc_C, wc_F, wc_Fl, wc_H, wc_LH, wc_L, wc_M, wc_O, wc_SH, wc_W,
28
+ wc_WB, wc_WF, wc_WFl, wc_WS):
29
+
30
+ if not model or not preprocessor:
31
+ return "Error", "Modelo o preprocesador no cargado."
32
+
33
+ # 1. Crear el DataFrame de entrada con las 31 columnas originales de X
34
+ input_data = pd.DataFrame({
35
+ 'Fighter_1_KD': [F1_KD], 'Fighter_2_KD': [F2_KD], 'Fighter_1_STR': [F1_STR], 'Fighter_2_STR': [F2_STR],
36
+ 'Fighter_1_TD': [F1_TD], 'Fighter_2_TD': [F2_TD], 'Fighter_1_SUB': [F1_SUB], 'Fighter_2_SUB': [F2_SUB],
37
+ 'Round': [Round], 'Fighter_1_accuracy': [F1_acc], 'Fighter_2_accuracy': [F2_acc],
38
+ 'KD_diff': [KD_diff], 'STR_diff': [STR_diff], 'TD_diff': [TD_diff], 'SUB_diff': [SUB_diff],
39
+ 'Location': [Location],
40
+ # Columnas OHE ya existentes en el dataset (passthrough)
41
+ 'weight_class_Bantamweight': [wc_B], 'weight_class_Catch Weight': [wc_C], 'weight_class_Featherweight': [wc_F],
42
+ 'weight_class_Flyweight': [wc_Fl], 'weight_class_Heavyweight': [wc_H], 'weight_class_Light Heavyweight': [wc_LH],
43
+ 'weight_class_Lightweight': [wc_L], 'weight_class_Middleweight': [wc_M], 'weight_class_Open Weight': [wc_O],
44
+ 'weight_class_Super Heavyweight': [wc_SH], 'weight_class_Welterweight': [wc_W],
45
+ "weight_class_Women's Bantamweight": [wc_WB], "weight_class_Women's Featherweight": [wc_WF],
46
+ "weight_class_Women's Flyweight": [wc_WFl], "weight_class_Women's Strawweight": [wc_WS]
47
+ })
48
+
49
+ # 2. Preprocesamiento: Utilizar el ColumnTransformer ajustado.
50
+ # Esto escala las estad铆sticas y aplica OHE a 'Location'.
51
+ X_processed = preprocessor.transform(input_data)
52
+
53
+ # 3. Convertir a DataFrame y asegurar el orden de las columnas (CRUCIAL)
54
+ X_final = pd.DataFrame(X_processed, columns=model_columns)
55
+
56
+ # 4. Predicci贸n
57
+ prediction_proba = model.predict_proba(X_final)[0][1] # Probabilidad de 1 (KO/TKO)
58
+
59
+ # 5. Formato de Salida
60
+ prob_str = f"{prediction_proba*100:.2f}%"
61
+ result_str = 'KO/TKO (隆Alta probabilidad de finalizaci贸n!)' if prediction_proba > 0.5 else 'DECISI脫N/SUMISI脫N (Pelea a las tarjetas)'
62
+
63
+ return prob_str, result_str
64
+
65
+ # --- 3. Creaci贸n de la Interfaz Gradio ---
66
+ # Definici贸n de inputs (Simplificado con valores por defecto)
67
+ inputs = [
68
+ gr.Slider(0, 5, value=1, step=1, label="KD P1"), gr.Slider(0, 5, value=0, step=1, label="KD P2"),
69
+ gr.Slider(0, 300, value=70, label="STR P1"), gr.Slider(0, 300, value=50, label="STR P2"),
70
+ gr.Slider(0, 20, value=5, label="TD P1"), gr.Slider(0, 20, value=2, label="TD P2"),
71
+ gr.Slider(0, 5, value=0, step=1, label="SUB P1"), gr.Slider(0, 5, value=0, step=1, label="SUB P2"),
72
+ gr.Slider(1, 5, value=3, step=1, label="Ronda actual (Round)"),
73
+ 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)"),
74
+ gr.Slider(-5, 5, value=1, label="Diferencia de KD"), gr.Slider(-300, 300, value=20, label="Diferencia de STR"),
75
+ gr.Slider(-20, 20, value=3, label="Diferencia de TD"), gr.Slider(-5, 5, value=0, label="Diferencia de SUB"),
76
+ gr.Dropdown(df['Location'].unique().tolist(), value='Las Vegas, NV', label="Ubicaci贸n"),
77
+ # Se a帽ade la categor铆a de peso como un switch binario (el usuario selecciona 1 y el resto 0)
78
+ gr.Checkbox(value=True, label="Lightweight (wc_L)"), gr.Checkbox(value=False, label="Bantamweight (wc_B)"),
79
+ gr.Checkbox(value=False, label="Catch Weight (wc_C)"), gr.Checkbox(value=False, label="Featherweight (wc_F)"),
80
+ gr.Checkbox(value=False, label="Flyweight (wc_Fl)"), gr.Checkbox(value=False, label="Heavyweight (wc_H)"),
81
+ gr.Checkbox(value=False, label="Light Heavyweight (wc_LH)"), gr.Checkbox(value=False, label="Middleweight (wc_M)"),
82
+ gr.Checkbox(value=False, label="Open Weight (wc_O)"), gr.Checkbox(value=False, label="Super Heavyweight (wc_SH)"),
83
+ gr.Checkbox(value=False, label="Welterweight (wc_W)"), gr.Checkbox(value=False, label="Women's Bantamweight (wc_WB)"),
84
+ gr.Checkbox(value=False, label="Women's Featherweight (wc_WF)"), gr.Checkbox(value=False, label="Women's Flyweight (wc_WFl)"),
85
+ gr.Checkbox(value=False, label="Women's Strawweight (wc_WS)")
86
+ ]
87
+
88
+ outputs = [gr.Textbox(label="Probabilidad de KO/TKO (%)"), gr.Textbox(label="Resultado M谩s Probable")]
89
+
90
+ gr.Interface(
91
+ fn=predict_ko_tko,
92
+ inputs=inputs,
93
+ outputs=outputs,
94
+ title="馃 Predictor de KO/TKO en Combates UFC (Despliegue ML)",
95
+ description="Modelo Random Forest para predecir la finalizaci贸n de un combate. El modelo usa estad铆sticas de los peleadores y el contexto del evento."
96
+ ).launch(server_name="0.0.0.0", server_port=7860)
model.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:47b3025851dec4bcb71ed75ad1cad89324a0d93c490824b74c8e751733a4ae77
3
+ size 12905769
model_columns.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:448bedf417d5e97e35963c15fae216ef0f3dede72f902fd063ea9d272638b96c
3
+ size 8071
preprocessor.pkl ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ version https://git-lfs.github.com/spec/v1
2
+ oid sha256:c596cb0100d36aad090795256e4531af7527b82c7ef3be2f097c6d7404ed7868
3
+ size 10967
requirements (1).txt ADDED
@@ -0,0 +1,6 @@
 
 
 
 
 
 
 
1
+ # requirements.txt
2
+ pandas
3
+ numpy
4
+ scikit-learn
5
+ gradio==4.3.0
6
+ joblib