import gradio as gr import joblib import numpy as np # 模型載入(需確認這些檔案存在於 Hugging Face Space 中) clf_result = joblib.load("clf_result.pkl") clf_cov = joblib.load("clf_cov.pkl") clf_ou = joblib.load("clf_ou.pkl") clf_score = joblib.load("clf_score.pkl") score_classes = joblib.load("score_classes.pkl") def parse_ah(value): try: if '/' in value: parts = value.replace('+', '').split('/') return round((float(parts[0]) + float(parts[1])) / 2, 2) else: return float(value.replace('+', '')) except: raise ValueError("❌ 讓球盤格式錯誤,請輸入 0.5 或 +0.5/+1") def predict_all(B365H, B365D, B365A, Over25, Under25, AHCh, AHH, AHA): try: prob_h = 1 / float(B365H) prob_d = 1 / float(B365D) prob_a = 1 / float(B365A) sum_prob = prob_h + prob_d + prob_a imp_prob_h = prob_h / sum_prob imp_prob_d = prob_d / sum_prob imp_prob_a = prob_a / sum_prob over_prob = 1 / float(Over25) under_prob = 1 / float(Under25) over_diff = over_prob - under_prob ah_diff = float(AHH) - float(AHA) ah_value = parse_ah(AHCh) features = [[imp_prob_h, imp_prob_d, imp_prob_a, over_diff, ah_diff, ah_value]] prob_res = clf_result.predict_proba(features)[0] pred_res = clf_result.classes_[prob_res.argmax()] prob_cov = clf_cov.predict_proba(features)[0] pred_cov = "Covered" if prob_cov[1] >= 0.5 else "Not Covered" prob_ou = clf_ou.predict_proba(features)[0] pred_ou = "Over" if prob_ou[1] >= 0.5 else "Under" prob_score = clf_score.predict_proba(features)[0] top3_idx = prob_score.argsort()[::-1][:3] top3_scores = [(score_classes[i], prob_score[i]) for i in top3_idx] score_text = "\n".join([f"🥇🥈🥉"[i] + f" {s}({p*100:.1f}%)" for i, (s, p) in enumerate(top3_scores)]) conf = max(prob_res.max(), prob_cov[1], prob_ou[1]) if conf >= 0.7: confidence = "High" elif conf >= 0.5: confidence = "Medium" else: confidence = "Low" return { "result": pred_res, "result_prob": round(prob_res.max(), 4), "handicap": pred_cov, "handicap_prob": round(max(prob_cov), 4), "ou": pred_ou, "ou_prob": round(max(prob_ou), 4), "confidence": confidence, "score_top3": top3_scores } except Exception as e: return {"error": str(e)} demo = gr.Interface( fn=predict_all, inputs=[ gr.Textbox(label="主勝賠率 B365H"), gr.Textbox(label="和局賠率 B365D"), gr.Textbox(label="客勝賠率 B365A"), gr.Textbox(label="Over 2.5 賠率"), gr.Textbox(label="Under 2.5 賠率"), gr.Textbox(label="讓球盤口(如 +0.5/+1)"), gr.Textbox(label="主隊讓球賠率 AHH"), gr.Textbox(label="客隊受讓賠率 AHA"), ], outputs="json", title="⚽ 比賽預測 API + UI", description="輸入盤口與賠率,預測勝負、過盤、大小、正確比分、信心等級", allow_flagging="never" ) demo.launch()