FPMLxDM / app.py
UmarAF's picture
Update app.py
981a51d verified
import gradio as gr
import pandas as pd
import numpy as np
import joblib
import pickle
try:
model = joblib.load('xgboost_valorant_model.pkl')
# Sesuaikan nama file dengan output training
with open('player_stats.pkl', 'rb') as f:
knowledge_base = pickle.load(f)
with open('model_columns.pkl', 'rb') as f:
training_columns = pickle.load(f)
print("โœ… Model dan Data berhasil dimuat.")
except Exception as e:
print(f"โŒ Error loading files: {e}")
# Dummy data untuk mencegah crash saat development lokal tanpa file
knowledge_base = {}
training_columns = []
# Daftar Map & Agent (Sesuaikan dengan data Anda)
MAP_LIST = ['Ascent', 'Bind', 'Breeze', 'Fracture', 'Haven', 'Icebox', 'Lotus', 'Pearl', 'Split', 'Sunset', 'Abyss', 'Corrode']
AGENT_LIST = [
'Jett', 'Raze', 'Reyna', 'Phoenix', 'Yoru', 'Neon', 'Iso', 'Waylay', # Duelist
'Sova', 'Fade', 'Breach', 'Skye', 'Kayo', 'Gekko', 'Tejo', # Initiator
'Omen', 'Brimstone', 'Viper', 'Astra', 'Harbor', 'Clove', # Controller
'Sage', 'Cypher', 'Killjoy', 'Chamber', 'Deadlock', 'Vyse', 'Veto' # Sentinel
]
# --- 2. FUNGSI PREDIKSI ---
def predict_match(map_name, t1_side,
t1_p1_name, t1_p1_agent, t1_p2_name, t1_p2_agent,
t1_p3_name, t1_p3_agent, t1_p4_name, t1_p4_agent, t1_p5_name, t1_p5_agent,
t2_p1_name, t2_p1_agent, t2_p2_name, t2_p2_agent,
t2_p3_name, t2_p3_agent, t2_p4_name, t2_p4_agent, t2_p5_name, t2_p5_agent):
# A. Buat DataFrame Input Kosong
input_data = pd.DataFrame(columns=training_columns)
input_data.loc[0] = 0 # Isi baris pertama dengan 0 semua
# B. Helper: Ambil Stats dari Knowledge Base
def get_stats(player, agent):
# Normalisasi input nama player (strip whitespace)
player_clean = player.strip() if player else ""
key = (player_clean, agent)
# Ambil stats, default 0.5 jika tidak ada
stats = knowledge_base.get(key, {'Agent_WR': 0.5, 'General_WR': 0.5, 'Exp': 0})
return stats
# C. Isi Fitur Winrate (Skenario 4 Logic)
# Team 1 Inputs
t1_inputs = [
(t1_p1_name, t1_p1_agent), (t1_p2_name, t1_p2_agent), (t1_p3_name, t1_p3_agent),
(t1_p4_name, t1_p4_agent), (t1_p5_name, t1_p5_agent)
]
t1_general_wrs = []
for i, (p_name, p_agent) in enumerate(t1_inputs):
stats = get_stats(p_name, p_agent)
idx = i + 1
if f'T1_P{idx}_Agent_WR' in training_columns:
input_data.at[0, f'T1_P{idx}_Agent_WR'] = stats['Agent_WR']
if f'T1_P{idx}_General_WR' in training_columns:
input_data.at[0, f'T1_P{idx}_General_WR'] = stats['General_WR']
if f'T1_P{idx}_Agent_Exp' in training_columns:
input_data.at[0, f'T1_P{idx}_Agent_Exp'] = stats['Exp']
t1_general_wrs.append(stats['General_WR'])
# Team 2 Inputs
t2_inputs = [
(t2_p1_name, t2_p1_agent), (t2_p2_name, t2_p2_agent), (t2_p3_name, t2_p3_agent),
(t2_p4_name, t2_p4_agent), (t2_p5_name, t2_p5_agent)
]
t2_general_wrs = []
for i, (p_name, p_agent) in enumerate(t2_inputs):
stats = get_stats(p_name, p_agent)
idx = i + 1
if f'T2_P{idx}_Agent_WR' in training_columns:
input_data.at[0, f'T2_P{idx}_Agent_WR'] = stats['Agent_WR']
if f'T2_P{idx}_General_WR' in training_columns:
input_data.at[0, f'T2_P{idx}_General_WR'] = stats['General_WR']
if f'T2_P{idx}_Agent_Exp' in training_columns:
input_data.at[0, f'T2_P{idx}_Agent_Exp'] = stats['Exp']
t2_general_wrs.append(stats['General_WR'])
# D. Hitung WR Diff
if 'WR_Diff' in training_columns:
t1_avg = np.mean(t1_general_wrs)
t2_avg = np.mean(t2_general_wrs)
input_data.at[0, 'WR_Diff'] = t1_avg - t2_avg
# E. One-Hot Encoding Manual
# Map
map_col = f'MAP_{map_name}'
if map_col in training_columns:
input_data.at[0, map_col] = 1
# Start Side
if 'T1_StartSide_Defense' in training_columns:
input_data.at[0, 'T1_StartSide_Defense'] = 1 if t1_side == 'Defense' else 0
if 'T2_StartSide_Defense' in training_columns:
input_data.at[0, 'T2_StartSide_Defense'] = 1 if t1_side == 'Attack' else 0
# Agent OHE (Slot Based)
# T1 Agents
for i, (_, agent) in enumerate(t1_inputs):
col_name = f'T1_P{i+1}_Agent_{agent}'
if col_name in training_columns:
input_data.at[0, col_name] = 1
# T2 Agents
for i, (_, agent) in enumerate(t2_inputs):
col_name = f'T2_P{i+1}_Agent_{agent}'
if col_name in training_columns:
input_data.at[0, col_name] = 1
# ==============================================================================
# --- BAGIAN DEBUGGING YANG DITAMBAHKAN ---
# Log ini akan muncul di Terminal / Logs Hugging Face, bukan di UI
print("\n" + "="*40)
print(f"๐Ÿ” DEBUGGING PREDICTION INPUT")
print(f"Map: {map_name} | T1 Side: {t1_side}")
print("-" * 40)
print("๐Ÿ”ต TIM 1 STATS:")
for i, (p, a) in enumerate(t1_inputs):
# Ambil nilai yang sudah masuk ke input_data
wr = input_data.at[0, f'T1_P{i+1}_Agent_WR']
gen_wr = input_data.at[0, f'T1_P{i+1}_General_WR']
exp = input_data.at[0, f'T1_P{i+1}_Agent_Exp']
status = "โœ… FOUND" if wr != 0.5 or gen_wr != 0.5 else "โŒ NOT FOUND (Using Default)"
print(f" P{i+1}: {p:<15} ({a:<8}) | WR: {wr:.2f} | GenWR: {gen_wr:.2f} | Exp: {exp:<3} -> {status}")
print("-" * 40)
print("๐Ÿ”ด TIM 2 STATS:")
for i, (p, a) in enumerate(t2_inputs):
wr = input_data.at[0, f'T2_P{i+1}_Agent_WR']
gen_wr = input_data.at[0, f'T2_P{i+1}_General_WR']
exp = input_data.at[0, f'T2_P{i+1}_Agent_Exp']
status = "โœ… FOUND" if wr != 0.5 or gen_wr != 0.5 else "โŒ NOT FOUND (Using Default)"
print(f" P{i+1}: {p:<15} ({a:<8}) | WR: {wr:.2f} | GenWR: {gen_wr:.2f} | Exp: {exp:<3} -> {status}")
if 'WR_Diff' in training_columns:
print("-" * 40)
print(f"๐Ÿ“Š Final WR_Diff (T1 - T2): {input_data.at[0, 'WR_Diff']:.4f}")
if input_data.at[0, 'WR_Diff'] > 0:
print(" -> Tim 1 Secara Statistik Lebih Unggul.")
elif input_data.at[0, 'WR_Diff'] < 0:
print(" -> Tim 2 Secara Statistik Lebih Unggul.")
else:
print(" -> Kekuatan Statistik Seimbang (Netral).")
print("="*40 + "\n")
# ==============================================================================
# --- 3. PREDIKSI ---
input_data = input_data.astype(float)
try:
prob = model.predict_proba(input_data)[0]
win_prob_t1 = prob[1]
if win_prob_t1 > 0.5:
winner = "๐Ÿ”ต TEAM 1 WINS"
confidence = win_prob_t1
color = "blue"
else:
winner = "๐Ÿ”ด TEAM 2 WINS"
confidence = 1 - win_prob_t1
color = "red"
# Format Output Debugging ke UI juga (Optional)
debug_msg = "โœ… Data found for players."
# Cek jika banyak player not found (WR_Diff 0)
if 'WR_Diff' in input_data and input_data.at[0, 'WR_Diff'] == 0:
debug_msg = "โš ๏ธ WARNING: Player stats not found (WR_Diff = 0). Check spelling!"
return f"{winner}\nConfidence: {confidence:.1%}\n({debug_msg})"
except Exception as e:
return f"Error during prediction: {str(e)}"
# --- 3. UI GRADIO ---
with gr.Blocks(title="Valorant Match Predictor") as demo:
gr.Markdown("# ๐Ÿ”ฎ Valorant AI Predictor (Skenario 4)")
gr.Markdown("Prediksi pemenang berdasarkan sejarah performa player dan komposisi agent.")
with gr.Row():
with gr.Column():
map_input = gr.Dropdown(MAP_LIST, label="Select Map")
side_input = gr.Radio(["Attack", "Defense"], label="Team 1 Start Side", value="Attack")
with gr.Row():
# Team 1 Inputs
with gr.Column():
gr.Markdown("### ๐Ÿ”ต Team 1 Roster")
t1_p1_n = gr.Textbox(label="P1 Name", placeholder="e.g. f0rsakeN")
t1_p1_a = gr.Dropdown(AGENT_LIST, label="P1 Agent")
t1_p2_n = gr.Textbox(label="P2 Name", placeholder="e.g. mindfreak")
t1_p2_a = gr.Dropdown(AGENT_LIST, label="P2 Agent")
t1_p3_n = gr.Textbox(label="P3 Name")
t1_p3_a = gr.Dropdown(AGENT_LIST, label="P3 Agent")
t1_p4_n = gr.Textbox(label="P4 Name")
t1_p4_a = gr.Dropdown(AGENT_LIST, label="P4 Agent")
t1_p5_n = gr.Textbox(label="P5 Name")
t1_p5_a = gr.Dropdown(AGENT_LIST, label="P5 Agent")
# Team 2 Inputs
with gr.Column():
gr.Markdown("### ๐Ÿ”ด Team 2 Roster")
t2_p1_n = gr.Textbox(label="P1 Name", placeholder="e.g. Tenz")
t2_p1_a = gr.Dropdown(AGENT_LIST, label="P1 Agent")
t2_p2_n = gr.Textbox(label="P2 Name", placeholder="e.g. Zekken")
t2_p2_a = gr.Dropdown(AGENT_LIST, label="P2 Agent")
t2_p3_n = gr.Textbox(label="P3 Name")
t2_p3_a = gr.Dropdown(AGENT_LIST, label="P3 Agent")
t2_p4_n = gr.Textbox(label="P4 Name")
t2_p4_a = gr.Dropdown(AGENT_LIST, label="P4 Agent")
t2_p5_n = gr.Textbox(label="P5 Name")
t2_p5_a = gr.Dropdown(AGENT_LIST, label="P5 Agent")
btn = gr.Button("๐Ÿš€ PREDICT WINNER", variant="primary")
output = gr.Label(label="Prediction Result")
# Connect Button
btn.click(
fn=predict_match,
inputs=[
map_input, side_input,
t1_p1_n, t1_p1_a, t1_p2_n, t1_p2_a, t1_p3_n, t1_p3_a, t1_p4_n, t1_p4_a, t1_p5_n, t1_p5_a,
t2_p1_n, t2_p1_a, t2_p2_n, t2_p2_a, t2_p3_n, t2_p3_a, t2_p4_n, t2_p4_a, t2_p5_n, t2_p5_a
],
outputs=output
)
demo.launch()