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()