|
|
import gradio as gr |
|
|
import pandas as pd |
|
|
import numpy as np |
|
|
import joblib |
|
|
import pickle |
|
|
|
|
|
try: |
|
|
model = joblib.load('xgboost_valorant_model.pkl') |
|
|
|
|
|
|
|
|
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}") |
|
|
|
|
|
knowledge_base = {} |
|
|
training_columns = [] |
|
|
|
|
|
|
|
|
MAP_LIST = ['Ascent', 'Bind', 'Breeze', 'Fracture', 'Haven', 'Icebox', 'Lotus', 'Pearl', 'Split', 'Sunset', 'Abyss', 'Corrode'] |
|
|
AGENT_LIST = [ |
|
|
'Jett', 'Raze', 'Reyna', 'Phoenix', 'Yoru', 'Neon', 'Iso', 'Waylay', |
|
|
'Sova', 'Fade', 'Breach', 'Skye', 'Kayo', 'Gekko', 'Tejo', |
|
|
'Omen', 'Brimstone', 'Viper', 'Astra', 'Harbor', 'Clove', |
|
|
'Sage', 'Cypher', 'Killjoy', 'Chamber', 'Deadlock', 'Vyse', 'Veto' |
|
|
] |
|
|
|
|
|
|
|
|
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): |
|
|
|
|
|
|
|
|
input_data = pd.DataFrame(columns=training_columns) |
|
|
input_data.loc[0] = 0 |
|
|
|
|
|
|
|
|
def get_stats(player, agent): |
|
|
|
|
|
player_clean = player.strip() if player else "" |
|
|
key = (player_clean, agent) |
|
|
|
|
|
|
|
|
stats = knowledge_base.get(key, {'Agent_WR': 0.5, 'General_WR': 0.5, 'Exp': 0}) |
|
|
return stats |
|
|
|
|
|
|
|
|
|
|
|
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']) |
|
|
|
|
|
|
|
|
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']) |
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
|
|
|
map_col = f'MAP_{map_name}' |
|
|
if map_col in training_columns: |
|
|
input_data.at[0, map_col] = 1 |
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
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 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
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): |
|
|
|
|
|
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") |
|
|
|
|
|
|
|
|
|
|
|
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" |
|
|
|
|
|
|
|
|
debug_msg = "โ
Data found for players." |
|
|
|
|
|
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)}" |
|
|
|
|
|
|
|
|
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(): |
|
|
|
|
|
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") |
|
|
|
|
|
|
|
|
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") |
|
|
|
|
|
|
|
|
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() |