GoshawkVortexAI commited on
Commit
d6398e2
·
verified ·
1 Parent(s): 10b186a

Update app.py

Browse files
Files changed (1) hide show
  1. app.py +103 -103
app.py CHANGED
@@ -1,180 +1,180 @@
1
  import os
 
2
  import numpy as np
3
  import gradio as gr
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. POISSON DAĞILIMI İLE HARİTA TAHMİN MOTORU
17
  # ==========================================
18
- def calculate_poisson_probabilities(home_dpc, away_dpc, home_form, away_form, home_missing, away_missing):
 
 
 
 
19
  """
20
- Dota 2 BO3 maçları için takım güçlerini kullanarak beklenen harita sayılarını (Lambda) hesaplar.
21
- Poisson dağılımı ile 0, 1, 2 harita kazanma olasılıklarını matrise döker.
 
 
 
 
 
 
 
 
22
  """
23
- # 1. Takım Güçlerini Hesaplama
24
- # DPC puanı: Yüksek puan = güçlü takım. (Puan / 1000) + 1 taban güç
25
- home_rank_power = (home_dpc / 1000.0) + 1.0
26
- away_rank_power = (away_dpc / 1000.0) + 1.0
27
 
28
- # Form gücü: Son 5 maç formu (0-5 arası galibiyet). (Form / 5) * 1.5 + 0.5
29
- home_form_power = (home_form / 5.0) * 1.5 + 0.5
30
- away_form_power = (away_form / 5.0) * 1.5 + 0.5
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
31
 
32
- # Eksik oyuncu cezası: Her eksik oyuncu gücü %15 düşürür
33
  home_penalty = max(0.4, 1.0 - (home_missing * 0.15))
34
  away_penalty = max(0.4, 1.0 - (away_missing * 0.15))
35
 
36
- # Turnuva/Ev sahibi avantajı (Dota 2'de genelde %10)
37
  home_advantage = 1.10
38
 
39
- # 2. Beklenen Harita Kazanma Sayıları (Lambda - λ)
40
- # BO3'te temel harita kazanma ortalaması: Ev için 1.4, Deplasman için 1.1
41
- base_home_maps = 1.4
42
- base_away_maps = 1.1
43
 
44
- lambda_home = base_home_maps * home_rank_power * home_form_power * home_penalty * home_advantage
45
- lambda_away = base_away_maps * away_rank_power * away_form_power * away_penalty
46
-
47
- # Lambda değerlerini BO3 mantığına sıkıştır (0.1 ile 2.5 arası)
48
  lambda_home = max(0.1, min(2.5, lambda_home))
49
  lambda_away = max(0.1, min(2.5, lambda_away))
50
 
51
- # 3. Poisson Matrisi (0, 1, 2 harita kazanma)
52
  max_maps = 2
53
  home_probs = [poisson.pmf(i, lambda_home) for i in range(max_maps + 1)]
54
  away_probs = [poisson.pmf(i, lambda_away) for i in range(max_maps + 1)]
55
 
56
- # Skor matrisi (Ev x Deplasman harita sayısı)
57
  score_matrix = np.outer(home_probs, away_probs)
58
 
59
- # 4. Maç Kazanma Olasılıklarını Toplama (BO3 formatına göre)
60
- # Ev kazanır: 2-0 veya 2-1
61
  p_home_win = score_matrix[2, 0] + score_matrix[2, 1]
62
- # Deplasman kazanır: 0-2 veya 1-2
63
  p_away_win = score_matrix[0, 2] + score_matrix[1, 2]
64
- # Beraberlik Dota 2'de olmaz, ama matris bütünlüğü için 1-1 durumu (teorik)
65
  p_draw = score_matrix[1, 1]
66
 
67
  return p_home_win, p_draw, p_away_win, lambda_home, lambda_away, score_matrix
68
 
69
  # ==========================================
70
- # 🧠 3. TAHMİN VE ANALİZ MOTORU
71
  # ==========================================
72
- def predict_and_analyze(home_team, away_team, home_dpc, away_dpc, home_form, away_form, home_missing, away_missing):
73
  if not home_team or not away_team:
74
- return "Lütfen ev sahibi ve deplasman takımlarının isimlerini giriniz.", {}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
75
 
76
  p_home, p_draw, p_away, lam_home, lam_away, score_matrix = calculate_poisson_probabilities(
77
- home_dpc, away_dpc, home_form, away_form, home_missing, away_missing
78
  )
79
 
80
- # En olası harita skorunu bulma
81
- max_prob_idx = np.unravel_index(np.argmax(score_matrix), score_matrix.shape)
82
- most_likely_score = f"{max_prob_idx[0]} - {max_prob_idx[1]}"
83
- most_likely_prob = score_matrix[max_prob_idx] * 100
84
 
85
- # Gradio grafiği için dictionary formatı
86
  prob_dict = {
87
- f"{home_team} Kazanır (2-0 / 2-1)": float(p_home),
88
- f"{away_team} Kazanır (0-2 / 1-2)": float(p_away),
89
  "Teorik Beraberlik (1-1)": float(p_draw)
90
  }
91
 
92
- prompt = f"""
93
- Sen uzman bir Dota 2 analisti ve profesyonel bir veri modelleyicisisin.
94
-
95
- Karşılaşma: {home_team} vs {away_team} (BO3 Formatı)
96
 
97
- İstatistiksel Göstergeler:
98
- - {home_team}: DPC Puanı: {home_dpc}, Son 5 Maç Formu (Galibiyet): {home_form}, Eksik Oyuncu: {home_missing}
99
- - {away_team}: DPC Puanı: {away_dpc}, Son 5 Maç Formu (Galibiyet): {away_form}, Eksik Oyuncu: {away_missing}
100
 
101
- Poisson Dağılım Modeli Sonuçları (Harita Bazlı):
102
- - Beklenen Harita Kazanma Sayıları (λ): {home_team} {lam_home:.2f} - {away_team} {lam_away:.2f}
103
- - {home_team} Maçı Kazanma Olasılığı (2-0 veya 2-1): %{p_home*100:.1f}
104
- - {away_team} Maçı Kazanma Olasılığı (0-2 veya 1-2): %{p_away*100:.1f}
105
- - En Olası Harita Skoru: {most_likely_score} (Olasılık: %{most_likely_prob:.1f})
106
 
107
- Yukarıdaki matematiksel olasılıkları ve takım durumlarını analiz ederek Türkçe bir rapor hazırla. Raporda şu başlıklar mutlaka bulunsun:
108
- 1. 🎯 Model Yorumu (Poisson dağılımı ve beklenen harita sayılarının mantığı)
109
  2. 🗺️ Olası Harita Skoru ve Draft Değerlendirmesi
110
- 3. 💡 Değerli Bahis Önerisi (Handikap, Toplam Harita Üst/Alt, +EV Değerlendirmesi)
111
-
112
- Yorumların rasyonel, nesnel ve profesyonel olsun.
113
  """
114
 
115
- if client:
116
- try:
117
- response = client.chat.completions.create(
118
- model="openai/gpt-oss-120b",
119
- messages=[
120
- {"role": "user", "content": prompt}
121
- ],
122
- temperature=0.3,
123
- max_tokens=1024
124
- )
125
- analysis_result = response.choices[0].message.content
126
- except Exception as e:
127
- 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.)"
128
- else:
129
- analysis_result = "Groq API Anahtarı bulunamadı! Lütfen Hugging Face Space alanına 'GROQ_API_KEY' adıyla bir Secret ekleyin. (Yine de yukarıdaki Poisson grafik tahminini görebilirsiniz.)"
130
 
131
  return analysis_result, prob_dict
132
 
133
  # ==========================================
134
- # 🎨 4. GRADIO ARAYÜZÜ
135
  # ==========================================
136
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="red", secondary_hue="slate")) as demo:
137
  gr.Markdown(
138
  """
139
- # 🎮 Dota 2 Poisson Dağılımı & Groq Hibrit Maç Tahmin Radarı
140
- Bu uygulama, girdiğiniz takım verilerini **Poisson Dağılımı** ile analiz ederek BO3 maçlarda beklenen harita sayılarını ve maç kazanma olasılıklarını hesaplar, ardından **Groq (GPT-OSS)** yapay zekası ile matematiksel olarak yorumlar.
141
  """
142
  )
143
 
144
  with gr.Row():
145
  with gr.Column():
146
- gr.Markdown("### ⚔️ Takım İsimleri")
147
- home_input = gr.Textbox(label="Takım 1 (Ev Sahibi)", value="Team Spirit")
148
- away_input = gr.Textbox(label="Takım 2 (Deplasman)", value="Gaimin Gladiators")
149
-
150
- gr.Markdown("### 📊 DPC ve Form Durumu")
151
- with gr.Row():
152
- home_dpc_input = gr.Number(label="Takım 1 DPC Puanı", value=1500, precision=0)
153
- away_dpc_input = gr.Number(label="Takım 2 DPC Puanı", value=800, precision=0)
154
- with gr.Row():
155
- home_form_input = gr.Slider(label="Takım 1 Form (Son 5 Maç Galibiyet)", minimum=0, maximum=5, value=4, step=1)
156
- away_form_input = gr.Slider(label="Takım 2 Form (Son 5 Maç Galibiyet)", minimum=0, maximum=5, value=2, step=1)
157
- with gr.Row():
158
- home_miss_input = gr.Number(label="Takım 1 Eksik Oyuncu", value=0, precision=0)
159
- away_miss_input = gr.Number(label="Takım 2 Eksik Oyuncu", value=1, precision=0)
160
-
161
- submit_btn = gr.Button("Analiz Et ve Tahmin Üret", variant="primary")
162
 
163
  with gr.Column():
164
- gr.Markdown("### 📈 Matematiksel Maç Kazanma Olasılıkları (Poisson)")
165
- prob_output = gr.Label(label="Olasılık Dağılımı")
166
-
167
- gr.Markdown("### 🧠 Groq Yapay Zeka Analiz Raporu")
168
- analysis_output = gr.Markdown(value="Verileri girdikten sonra butona basarak analizi başlatabilirsiniz.")
169
 
170
  submit_btn.click(
171
  fn=predict_and_analyze,
172
- inputs=[
173
- home_input, away_input,
174
- home_dpc_input, away_dpc_input,
175
- home_form_input, away_form_input,
176
- home_miss_input, away_miss_input
177
- ],
178
  outputs=[analysis_output, prob_output]
179
  )
180
 
 
1
  import os
2
+ import json
3
  import numpy as np
4
  import gradio as gr
5
  from scipy.stats import poisson
6
  from groq import Groq
7
 
 
 
 
8
  api_key = os.environ.get("GROQ_API_KEY")
9
  client = None
10
  if api_key:
11
  client = Groq(api_key=api_key)
12
 
13
  # ==========================================
14
+ # 1. GROQ COMPOUND İLE VERİ ÇEKME
15
  # ==========================================
16
+ def fetch_team_data(team_name):
17
+ """
18
+ Groq Compound (web search destekli) kullanarak takımın güncel formunu ve
19
+ oyuncu durumunu çeker. DPC kaldırıldığı için 'takım güç puanı' olarak
20
+ turnuva sıralaması / son maç galibiyet oranı istenir.
21
  """
22
+ if not client:
23
+ return None
24
+
25
+ prompt = f"""
26
+ Search the web for the latest information about the Dota 2 team "{team_name}".
27
+ Find and return ONLY a JSON object with these fields:
28
+ - "form": number of wins in their last 5 professional matches (integer 0-5)
29
+ - "missing_players": number of players currently missing or using stand-ins (integer 0-5)
30
+ - "power_score": a rough strength score (integer 1-2000) based on recent tournament placements/rankings
31
+ If exact data is unavailable, estimate reasonably from recent news. Return ONLY valid JSON, no other text.
32
  """
 
 
 
 
33
 
34
+ try:
35
+ response = client.chat.completions.create(
36
+ model="groq/compound",
37
+ messages=[{"role": "user", "content": prompt}],
38
+ temperature=0.2,
39
+ max_tokens=512
40
+ )
41
+ content = response.choices[0].message.content.strip()
42
+ # JSON bloğunu çıkar
43
+ start = content.find("{")
44
+ end = content.rfind("}") + 1
45
+ if start != -1 and end != 0:
46
+ data = json.loads(content[start:end])
47
+ return data
48
+ except Exception as e:
49
+ print(f"Groq fetch error for {team_name}: {e}")
50
+ return None
51
+
52
+ # ==========================================
53
+ # 2. POISSON MODELİ (BO3)
54
+ # ==========================================
55
+ def calculate_poisson_probabilities(home_power, away_power, home_form, away_form, home_missing, away_missing):
56
+ home_power_norm = max(0.5, home_power / 1000.0)
57
+ away_power_norm = max(0.5, away_power / 1000.0)
58
+
59
+ home_form_norm = (home_form / 5.0) * 1.5 + 0.5
60
+ away_form_norm = (away_form / 5.0) * 1.5 + 0.5
61
 
 
62
  home_penalty = max(0.4, 1.0 - (home_missing * 0.15))
63
  away_penalty = max(0.4, 1.0 - (away_missing * 0.15))
64
 
 
65
  home_advantage = 1.10
66
 
67
+ lambda_home = 1.4 * home_power_norm * home_form_norm * home_penalty * home_advantage
68
+ lambda_away = 1.1 * away_power_norm * away_form_norm * away_penalty
 
 
69
 
 
 
 
 
70
  lambda_home = max(0.1, min(2.5, lambda_home))
71
  lambda_away = max(0.1, min(2.5, lambda_away))
72
 
 
73
  max_maps = 2
74
  home_probs = [poisson.pmf(i, lambda_home) for i in range(max_maps + 1)]
75
  away_probs = [poisson.pmf(i, lambda_away) for i in range(max_maps + 1)]
76
 
 
77
  score_matrix = np.outer(home_probs, away_probs)
78
 
 
 
79
  p_home_win = score_matrix[2, 0] + score_matrix[2, 1]
 
80
  p_away_win = score_matrix[0, 2] + score_matrix[1, 2]
 
81
  p_draw = score_matrix[1, 1]
82
 
83
  return p_home_win, p_draw, p_away_win, lambda_home, lambda_away, score_matrix
84
 
85
  # ==========================================
86
+ # 3. ANALİZ FONKSİYONU
87
  # ==========================================
88
+ def predict_and_analyze(home_team, away_team):
89
  if not home_team or not away_team:
90
+ return "Lütfen iki takım adı da giriniz.", {}
91
+
92
+ if not client:
93
+ return "GROQ_API_KEY bulunamadı!", {}
94
+
95
+ # Verileri Groq Compound ile çek
96
+ home_data = fetch_team_data(home_team)
97
+ away_data = fetch_team_data(away_team)
98
+
99
+ if not home_data or not away_data:
100
+ return "Takım verileri çekilemedi. Lütfen takım adlarını kontrol edin veya tekrar deneyin.", {}
101
+
102
+ home_power = home_data.get("power_score", 500)
103
+ away_power = away_data.get("power_score", 500)
104
+ home_form = home_data.get("form", 2)
105
+ away_form = away_data.get("form", 2)
106
+ home_missing = home_data.get("missing_players", 0)
107
+ away_missing = away_data.get("missing_players", 0)
108
 
109
  p_home, p_draw, p_away, lam_home, lam_away, score_matrix = calculate_poisson_probabilities(
110
+ home_power, away_power, home_form, away_form, home_missing, away_missing
111
  )
112
 
113
+ max_idx = np.unravel_index(np.argmax(score_matrix), score_matrix.shape)
114
+ most_likely_score = f"{max_idx[0]} - {max_idx[1]}"
115
+ most_likely_prob = score_matrix[max_idx] * 100
 
116
 
 
117
  prob_dict = {
118
+ f"{home_team} Kazanır": float(p_home),
119
+ f"{away_team} Kazanır": float(p_away),
120
  "Teorik Beraberlik (1-1)": float(p_draw)
121
  }
122
 
123
+ # Groq ile analiz raporu (compound, güncel bağlamı da yakalar)
124
+ analysis_prompt = f"""
125
+ Sen uzman bir Dota 2 analistisin. Aşağıdaki verilere göre Türkçe bir rapor yaz:
 
126
 
127
+ {home_team}: Güç Puanı {home_power}, Son 5 Maç Formu {home_form}/5, Eksik Oyuncu {home_missing}
128
+ {away_team}: Güç Puanı {away_power}, Son 5 Maç Formu {away_form}/5, Eksik Oyuncu {away_missing}
 
129
 
130
+ Poisson Modeli:
131
+ - Beklenen Harita: {home_team} {lam_home:.2f} - {away_team} {lam_away:.2f}
132
+ - Kazanma: {home_team} %{p_home*100:.1f}, {away_team} %{p_away*100:.1f}
133
+ - En Olası Skor: {most_likely_score} (%{most_likely_prob:.1f})
 
134
 
135
+ Rapor başlıkları:
136
+ 1. 🎯 Model Yorumu
137
  2. 🗺️ Olası Harita Skoru ve Draft Değerlendirmesi
138
+ 3. 💡 Değerli Bahis Önerisi (Handikap / Toplam Harita)
 
 
139
  """
140
 
141
+ try:
142
+ analysis_resp = client.chat.completions.create(
143
+ model="groq/compound",
144
+ messages=[{"role": "user", "content": analysis_prompt}],
145
+ temperature=0.3,
146
+ max_tokens=1024
147
+ )
148
+ analysis_result = analysis_resp.choices[0].message.content
149
+ except Exception as e:
150
+ analysis_result = f"Analiz raporu oluşturulamadı: {e}"
 
 
 
 
 
151
 
152
  return analysis_result, prob_dict
153
 
154
  # ==========================================
155
+ # 4. GRADIO ARAYÜZÜ (Sadece takım isimleri)
156
  # ==========================================
157
  with gr.Blocks(theme=gr.themes.Soft(primary_hue="red", secondary_hue="slate")) as demo:
158
  gr.Markdown(
159
  """
160
+ # 🎮 Dota 2 Poisson Tahmin Radarı (Groq Compound)
161
+ Takım adlarını girin; **Groq Compound** web araması ile güncel form, oyuncu eksikliği ve güç puanını çeker, **Poisson** modeli ile BO3 kazanma olasılıklarını hesaplar.
162
  """
163
  )
164
 
165
  with gr.Row():
166
  with gr.Column():
167
+ home_input = gr.Textbox(label="Takım 1", value="Team Spirit")
168
+ away_input = gr.Textbox(label="Takım 2", value="Gaimin Gladiators")
169
+ submit_btn = gr.Button("Verileri Çek ve Analiz Et", variant="primary")
 
 
 
 
 
 
 
 
 
 
 
 
 
170
 
171
  with gr.Column():
172
+ prob_output = gr.Label(label="Kazanma Olasılıkları")
173
+ analysis_output = gr.Markdown(value="Butona basınca Groq verileri çekip analiz edecek.")
 
 
 
174
 
175
  submit_btn.click(
176
  fn=predict_and_analyze,
177
+ inputs=[home_input, away_input],
 
 
 
 
 
178
  outputs=[analysis_output, prob_output]
179
  )
180