GoshawkVortexAI commited on
Commit
4315990
·
verified ·
1 Parent(s): a297a14

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +137 -72
app.py CHANGED
@@ -4,134 +4,199 @@ import gradio as gr
4
  from scipy.stats import poisson
5
  from groq import Groq
6
 
 
 
 
7
  api_key = os.environ.get("GROQ_API_KEY")
8
  client = None
9
  if api_key:
10
  client = Groq(api_key=api_key)
11
 
12
  # ==========================================
13
- # POISSON MODELİ (BO3)
14
  # ==========================================
15
- def calculate_poisson_probabilities(home_power, away_power, home_form, away_form, home_missing, away_missing):
16
- home_power_norm = max(0.5, home_power / 1000.0)
17
- away_power_norm = max(0.5, away_power / 1000.0)
 
 
 
 
 
 
 
18
 
19
- home_form_norm = (home_form / 5.0) * 1.5 + 0.5
20
- away_form_norm = (away_form / 5.0) * 1.5 + 0.5
 
21
 
22
- home_penalty = max(0.4, 1.0 - (home_missing * 0.15))
23
- away_penalty = max(0.4, 1.0 - (away_missing * 0.15))
 
24
 
25
- home_advantage = 1.10
 
26
 
27
- lambda_home = 1.4 * home_power_norm * home_form_norm * home_penalty * home_advantage
28
- lambda_away = 1.1 * away_power_norm * away_form_norm * away_penalty
 
 
29
 
30
- lambda_home = max(0.1, min(2.5, lambda_home))
31
- lambda_away = max(0.1, min(2.5, lambda_away))
32
 
33
- max_maps = 2
34
- home_probs = [poisson.pmf(i, lambda_home) for i in range(max_maps + 1)]
35
- away_probs = [poisson.pmf(i, lambda_away) for i in range(max_maps + 1)]
36
 
37
- score_matrix = np.outer(home_probs, away_probs)
 
 
 
38
 
39
- p_home_win = score_matrix[2, 0] + score_matrix[2, 1]
40
- p_away_win = score_matrix[0, 2] + score_matrix[1, 2]
41
- p_draw = score_matrix[1, 1]
42
 
43
- return p_home_win, p_draw, p_away_win, lambda_home, lambda_away, score_matrix
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
44
 
45
  # ==========================================
46
- # ANALİZ FONKSİYONU (Manuel Veri Girişi)
47
  # ==========================================
48
- def predict_and_analyze(home_team, away_team, home_power, away_power, home_form, away_form, home_missing, away_missing):
 
49
  if not home_team or not away_team:
50
- return "Lütfen iki takım adı da giriniz.", {}
51
 
52
- if not client:
53
- return "GROQ_API_KEY bulunamadı!", {}
54
-
55
- p_home, p_draw, p_away, lam_home, lam_away, score_matrix = calculate_poisson_probabilities(
56
- home_power, away_power, home_form, away_form, home_missing, away_missing
57
  )
58
 
 
59
  max_idx = np.unravel_index(np.argmax(score_matrix), score_matrix.shape)
60
  most_likely_score = f"{max_idx[0]} - {max_idx[1]}"
61
  most_likely_prob = score_matrix[max_idx] * 100
62
 
 
63
  prob_dict = {
64
- f"{home_team} Kazanır": float(p_home),
65
- f"{away_team} Kazanır": float(p_away),
66
- "Teorik Beraberlik (1-1)": float(p_draw)
67
  }
68
 
69
- # Groq standart model ile analiz (web arama yok, sadece hesaplanan verilere dayanır)
70
- analysis_prompt = f"""
71
- Sen uzman bir Dota 2 analistisin. Aşağıdaki verilere göre Türkçe bir rapor yaz:
 
 
 
72
 
73
- {home_team}: Güç Puanı {home_power}, Son 5 Maç Formu {home_form}/5, Eksik Oyuncu {home_missing}
74
- {away_team}: Güç Puanı {away_power}, Son 5 Maç Formu {away_form}/5, Eksik Oyuncu {away_missing}
 
75
 
76
- Poisson Modeli (BO3):
77
- - Beklenen Harita: {home_team} {lam_home:.2f} - {away_team} {lam_away:.2f}
78
- - Kazanma: {home_team} %{p_home*100:.1f}, {away_team} %{p_away*100:.1f}
 
 
79
  - En Olası Skor: {most_likely_score} (%{most_likely_prob:.1f})
 
 
 
 
 
 
 
80
 
81
- Rapor başlıkları:
82
- 1. 🎯 Model Yorumu
83
- 2. 🗺️ Olası Harita Skoru ve Draft Değerlendirmesi
84
- 3. 💡 Değerli Bahis Önerisi (Handikap / Toplam Harita)
85
  """
86
 
87
- try:
88
- analysis_resp = client.chat.completions.create(
89
- model="openai/gpt-oss-120b", # Compound yerine standart model
90
- messages=[{"role": "user", "content": analysis_prompt}],
91
- temperature=0.3,
92
- max_tokens=1024
93
- )
94
- analysis_result = analysis_resp.choices[0].message.content
95
- except Exception as e:
96
- analysis_result = f"Analiz raporu oluşturulamadı: {e}"
 
 
 
 
97
 
98
  return analysis_result, prob_dict
99
 
100
  # ==========================================
101
- # GRADIO ARAYÜZÜ (Manuel Giriş)
102
  # ==========================================
103
- with gr.Blocks(theme=gr.themes.Soft(primary_hue="red", secondary_hue="slate")) as demo:
104
  gr.Markdown(
105
  """
106
- # 🎮 Dota 2 Poisson Tahmin Radarı
107
- Takım verilerini manuel olarak girin; **Poisson** modeli BO3 kazanma olasılıklarını hesaplar, **Groq** analiz raporu üretir.
108
  """
109
  )
110
 
111
  with gr.Row():
112
  with gr.Column():
113
- home_input = gr.Textbox(label="Takım 1", value="Team Spirit")
114
- away_input = gr.Textbox(label="Takım 2", value="Gaimin Gladiators")
 
115
 
116
- home_power_input = gr.Number(label="Takım 1 Güç Puanı (1-2000)", value=1500)
117
- away_power_input = gr.Number(label="Takım 2 Güç Puanı (1-2000)", value=800)
 
 
118
 
119
- home_form_input = gr.Slider(label="Takım 1 Form (Son 5 Maç Galibiyet)", minimum=0, maximum=5, value=4, step=1)
120
- away_form_input = gr.Slider(label="Takım 2 Form (Son 5 Maç Galibiyet)", minimum=0, maximum=5, value=2, step=1)
 
 
 
 
 
121
 
122
- home_miss_input = gr.Number(label="Takım 1 Eksik Oyuncu", value=0)
123
- away_miss_input = gr.Number(label="Takım 2 Eksik Oyuncu", value=1)
124
-
125
- submit_btn = gr.Button("Analiz Et", variant="primary")
126
 
127
  with gr.Column():
128
- prob_output = gr.Label(label="Kazanma Olasılıkları")
129
- analysis_output = gr.Markdown(value="Verileri girip butona basın.")
 
 
 
130
 
131
  submit_btn.click(
132
  fn=predict_and_analyze,
133
- inputs=[home_input, away_input, home_power_input, away_power_input,
134
- home_form_input, away_form_input, home_miss_input, away_miss_input],
 
 
 
 
135
  outputs=[analysis_output, prob_output]
136
  )
137
 
 
4
  from scipy.stats import poisson
5
  from groq import Groq
6
 
7
+ # ==========================================
8
+ # 🔌 1. GROQ CLIENT BAŞLATMA
9
+ # ==========================================
10
  api_key = os.environ.get("GROQ_API_KEY")
11
  client = None
12
  if api_key:
13
  client = Groq(api_key=api_key)
14
 
15
  # ==========================================
16
+ # ⚽ 2. FIFA H2H POISSON GOL TAHMİN MOTORU
17
  # ==========================================
18
+ def calculate_poisson_probabilities(home_rating, away_rating, home_form, away_form, home_injuries, away_injuries):
19
+ """
20
+ FIFA H2H sanal lig için Poisson tabanlı gol tahmini.
21
+ - rating: Takım genel gücü (1-99, FIFA Overall Rating)
22
+ - form: Son 5 maç formu (0-15 puan)
23
+ - injuries: Sakat/cezalı oyuncu sayısı
24
+ """
25
+ # 1. Takım güçlerini normalize et (FIFA rating 1-99 arası)
26
+ home_attack = max(0.5, home_rating / 70.0) # 70 ortalama rating kabul edildi
27
+ away_attack = max(0.5, away_rating / 70.0)
28
 
29
+ # 2. Form gücü (0-15 -> 0.5-2.0 çarpan)
30
+ home_form_power = (home_form / 15.0) * 1.5 + 0.5
31
+ away_form_power = (away_form / 15.0) * 1.5 + 0.5
32
 
33
+ # 3. Sakatlık cezası: her eksik oyuncu %12 güç kaybı
34
+ home_penalty = max(0.4, 1.0 - (home_injuries * 0.12))
35
+ away_penalty = max(0.4, 1.0 - (away_injuries * 0.12))
36
 
37
+ # 4. Ev sahibi avantajı (FIFA H2H'de ev sahibi ~%15 avantajlı)
38
+ home_advantage = 1.15
39
 
40
+ # 5. Beklenen gol sayıları (Lambda - λ)
41
+ # FIFA H2H ortalama gol: Ev ~1.6, Deplasman ~1.2
42
+ base_home_goals = 1.6
43
+ base_away_goals = 1.2
44
 
45
+ lambda_home = base_home_goals * home_attack * home_form_power * home_penalty * home_advantage
46
+ lambda_away = base_away_goals * away_attack * away_form_power * away_penalty
47
 
48
+ # Lambda değerlerini makul aralığa sıkıştır
49
+ lambda_home = max(0.1, min(4.5, lambda_home))
50
+ lambda_away = max(0.1, min(4.5, lambda_away))
51
 
52
+ # 6. Poisson matrisi (0-6 gol arası)
53
+ max_goals = 6
54
+ home_probs = [poisson.pmf(i, lambda_home) for i in range(max_goals + 1)]
55
+ away_probs = [poisson.pmf(i, lambda_away) for i in range(max_goals + 1)]
56
 
57
+ score_matrix = np.outer(home_probs, away_probs)
 
 
58
 
59
+ # 7. Sonuç olasılıkları
60
+ p_home_win = np.sum(np.tril(score_matrix, -1))
61
+ p_draw = np.sum(np.diag(score_matrix))
62
+ p_away_win = np.sum(np.triu(score_matrix, 1))
63
+
64
+ # 8. Alt/Üst 2.5 gol olasılığı
65
+ p_under_25 = 0.0
66
+ p_over_25 = 0.0
67
+ for i in range(max_goals + 1):
68
+ for j in range(max_goals + 1):
69
+ if i + j <= 2:
70
+ p_under_25 += score_matrix[i, j]
71
+ else:
72
+ p_over_25 += score_matrix[i, j]
73
+
74
+ # 9. Karşılıklı gol (BTTS) olasılığı
75
+ p_btts_yes = 0.0
76
+ for i in range(1, max_goals + 1):
77
+ for j in range(1, max_goals + 1):
78
+ p_btts_yes += score_matrix[i, j]
79
+
80
+ return (p_home_win, p_draw, p_away_win, lambda_home, lambda_away,
81
+ score_matrix, p_under_25, p_over_25, p_btts_yes)
82
 
83
  # ==========================================
84
+ # 🧠 3. TAHMİN VE ANALİZ MOTORU
85
  # ==========================================
86
+ def predict_and_analyze(home_team, away_team, home_rating, away_rating,
87
+ home_form, away_form, home_injuries, away_injuries):
88
  if not home_team or not away_team:
89
+ return "Lütfen ev sahibi ve deplasman takımlarının isimlerini giriniz.", {}
90
 
91
+ (p_home, p_draw, p_away, lam_home, lam_away,
92
+ score_matrix, p_under, p_over, p_btts) = calculate_poisson_probabilities(
93
+ home_rating, away_rating, home_form, away_form, home_injuries, away_injuries
 
 
94
  )
95
 
96
+ # En olası skoru bul
97
  max_idx = np.unravel_index(np.argmax(score_matrix), score_matrix.shape)
98
  most_likely_score = f"{max_idx[0]} - {max_idx[1]}"
99
  most_likely_prob = score_matrix[max_idx] * 100
100
 
101
+ # Gradio grafiği için olasılık sözlüğü
102
  prob_dict = {
103
+ f"{home_team} Galibiyeti (1)": float(p_home),
104
+ "Beraberlik (X)": float(p_draw),
105
+ f"{away_team} Galibiyeti (2)": float(p_away)
106
  }
107
 
108
+ prompt = f"""
109
+ Sen uzman bir FIFA (EA Sports FC) H2H sanal futbol analistisin.
110
+ Aşağıdaki verilere göre Türkçe bir maç öncesi analiz raporu hazırla.
111
+
112
+ ⚽ Karşılaşma: {home_team} (Ev) vs {away_team} (Deplasman)
113
+ 🏆 Format: FIFA H2H Sanal Ligi
114
 
115
+ 📊 Takım Güçleri (FIFA Overall Rating):
116
+ - {home_team}: Rating {home_rating}, Form (Son 5 Maç) {home_form}/15, Sakat/Cezalı {home_injuries}
117
+ - {away_team}: Rating {away_rating}, Form (Son 5 Maç) {away_form}/15, Sakat/Cezalı {away_injuries}
118
 
119
+ 📈 Poisson Modeli Sonuçları:
120
+ - Beklenen Gol (λ): {home_team} {lam_home:.2f} - {away_team} {lam_away:.2f}
121
+ - 1 (Ev Sahibi): %{p_home*100:.1f}
122
+ - X (Beraberlik): %{p_draw*100:.1f}
123
+ - 2 (Deplasman): %{p_away*100:.1f}
124
  - En Olası Skor: {most_likely_score} (%{most_likely_prob:.1f})
125
+ - Alt 2.5: %{p_under*100:.1f} | Üst 2.5: %{p_over*100:.1f}
126
+ - Karşılıklı Gol (BTTS): %{p_btts*100:.1f}
127
+
128
+ Raporda şu başlıklar bulunsun:
129
+ 1. 🎯 Model Yorumu (Poisson ve beklenen gollerin mantığı)
130
+ 2. ⚽ Olası Skor ve Gol Tahmini (Alt/Üst, BTTS değerlendirmesi)
131
+ 3. 💡 Değerli Bahis Önerisi (+EV değerlendirmesi)
132
 
133
+ Yorumların rasyonel, nesnel ve profesyonel olsun.
 
 
 
134
  """
135
 
136
+ if client:
137
+ try:
138
+ response = client.chat.completions.create(
139
+ model="openai/gpt-oss-120b",
140
+ messages=[{"role": "user", "content": prompt}],
141
+ temperature=0.3,
142
+ max_tokens=1024
143
+ )
144
+ analysis_result = response.choices[0].message.content
145
+ except Exception as e:
146
+ analysis_result = f"Groq API Analiz Hatası: {str(e)}\n\n(Lütfen GROQ_API_KEY değişkeninizi Hugging Face Secrets alanına doğru eklediğinizden emin olun.)"
147
+ else:
148
+ analysis_result = ("Groq API Anahtarı bulunamadı! Lütfen Hugging Face Space alanına "
149
+ "'GROQ_API_KEY' adıyla bir Secret ekleyin. (Yine de yukarıdaki Poisson grafik tahminini görebilirsiniz.)")
150
 
151
  return analysis_result, prob_dict
152
 
153
  # ==========================================
154
+ # 🎨 4. GRADIO ARAYÜZÜ
155
  # ==========================================
156
+ with gr.Blocks(theme=gr.themes.Soft(primary_hue="green", secondary_hue="slate")) as demo:
157
  gr.Markdown(
158
  """
159
+ # ⚽ FIFA H2H Sanal Lig Poisson Tahmin Radarı
160
+ Bu uygulama, FIFA H2H sanal lig maçları için **Poisson Dağılımı** kullanarak gol ve sonuç tahminleri üretir; ardından **Groq (GPT-OSS)** yapay zekası ile analiz raporu hazırlar.
161
  """
162
  )
163
 
164
  with gr.Row():
165
  with gr.Column():
166
+ gr.Markdown("### 🏟️ Takım İsimleri")
167
+ home_input = gr.Textbox(label="Ev Sahibi Takım", value="Real Madrid")
168
+ away_input = gr.Textbox(label="Deplasman Takım", value="Barcelona")
169
 
170
+ gr.Markdown("### ⭐ Takım Güçleri (FIFA Overall Rating)")
171
+ with gr.Row():
172
+ home_rating_input = gr.Number(label="Ev Sahibi Rating (1-99)", value=85, precision=0)
173
+ away_rating_input = gr.Number(label="Deplasman Rating (1-99)", value=84, precision=0)
174
 
175
+ gr.Markdown("### 📊 Form ve Sakatlık Durumu")
176
+ with gr.Row():
177
+ home_form_input = gr.Slider(label="Ev Form (Son 5 Maç Puanı, Max 15)", minimum=0, maximum=15, value=11, step=1)
178
+ away_form_input = gr.Slider(label="Deplasman Form (Son 5 Maç Puanı, Max 15)", minimum=0, maximum=15, value=9, step=1)
179
+ with gr.Row():
180
+ home_inj_input = gr.Number(label="Ev Sakat/Cezalı Sayısı", value=1, precision=0)
181
+ away_inj_input = gr.Number(label="Deplasman Sakat/Cezalı Sayısı", value=2, precision=0)
182
 
183
+ submit_btn = gr.Button("Analiz Et ve Tahmin Üret", variant="primary")
 
 
 
184
 
185
  with gr.Column():
186
+ gr.Markdown("### 📈 Maç Sonucu Olasılıkları (Poisson)")
187
+ prob_output = gr.Label(label="Olasılık Dağılımı")
188
+
189
+ gr.Markdown("### 🧠 Groq Yapay Zeka Analiz Raporu")
190
+ analysis_output = gr.Markdown(value="Verileri girdikten sonra butona basarak analizi başlatabilirsiniz.")
191
 
192
  submit_btn.click(
193
  fn=predict_and_analyze,
194
+ inputs=[
195
+ home_input, away_input,
196
+ home_rating_input, away_rating_input,
197
+ home_form_input, away_form_input,
198
+ home_inj_input, away_inj_input
199
+ ],
200
  outputs=[analysis_output, prob_output]
201
  )
202