Spaces:
Runtime error
Runtime error
ramonmedeiro1
commited on
Commit
•
c40ab65
1
Parent(s):
1c442f1
Subindo projeto no huggingface
Browse files- app.py +55 -0
- info_futebol.xlsx +0 -0
- tools.py +77 -0
app.py
ADDED
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
import pandas as pd
|
3 |
+
from scipy.stats import poisson
|
4 |
+
import tools
|
5 |
+
import streamlit as st
|
6 |
+
import matplotlib.pyplot as plt
|
7 |
+
import seaborn as sns
|
8 |
+
|
9 |
+
# Lendo arquivo excel
|
10 |
+
df = pd.read_excel('../datasets/info_futebol.xlsx', sheet_name='info_geral', index_col='Time')
|
11 |
+
|
12 |
+
# Criando coluna de força de times
|
13 |
+
a, b = df['Pontuacao'].min(), df['Pontuacao'].max()
|
14 |
+
fa, fb = 0.15, 1 # novos limites
|
15 |
+
b1 = (fb - fa)/(b-a)
|
16 |
+
b0 = fb - b*b1
|
17 |
+
df['forca'] = round(b0 + b1*df['Pontuacao'], 3)
|
18 |
+
|
19 |
+
# Streamlit Step
|
20 |
+
|
21 |
+
rad = st.sidebar.radio('Navegue pelos itens', ['Home', 'Sobre', 'BET Jogos', 'BET Campeonato'])
|
22 |
+
|
23 |
+
if rad == 'Home':
|
24 |
+
st.markdown(""" ## :soccer: BET-POISSON """)
|
25 |
+
st.write('Simulando jogos com base na distribuição de Poisson.')
|
26 |
+
|
27 |
+
if rad == 'Sobre':
|
28 |
+
st.write('Em construção')
|
29 |
+
|
30 |
+
if rad == 'BET Jogos':
|
31 |
+
times1 = list(df.index)
|
32 |
+
times2 = times1.copy()
|
33 |
+
casa, visitante = st.columns(2)
|
34 |
+
time1 = casa.selectbox('Time Casa', times1)
|
35 |
+
times2.remove(time1)
|
36 |
+
time2 = visitante.selectbox('Time Visitante', times2)
|
37 |
+
prob, matrix = tools.probabilidades_partidas(df, time1, time2)
|
38 |
+
|
39 |
+
|
40 |
+
col1, col2, col3, col4, col5 = st.columns(5)
|
41 |
+
col1.image(df.loc[time1, 'imagem'])
|
42 |
+
col2.metric(time1, prob[0])
|
43 |
+
col3.metric('Empate', prob[1])
|
44 |
+
col4.metric(time2, prob[2])
|
45 |
+
col5.image(df.loc[time2, 'imagem'])
|
46 |
+
|
47 |
+
if st.button('Mostrar mapa de calor dos placares'):
|
48 |
+
fig, ax = plt.subplots(figsize=(10, 5))
|
49 |
+
sns.heatmap(matrix, vmax = 19 , annot=True, linewidth = .5, fmt=".1f")
|
50 |
+
plt.xlabel(f'{time2}', fontsize=13)
|
51 |
+
plt.ylabel(f'{time1}', fontsize=13)
|
52 |
+
st.pyplot(fig)
|
53 |
+
|
54 |
+
if rad == 'BET Campeonato':
|
55 |
+
st.write('Em construção')
|
info_futebol.xlsx
ADDED
Binary file (5.84 kB). View file
|
|
tools.py
ADDED
@@ -0,0 +1,77 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import numpy as np
|
2 |
+
import pandas as pd
|
3 |
+
from scipy.stats import poisson
|
4 |
+
|
5 |
+
def lambda_(df, team1, team2):
|
6 |
+
|
7 |
+
forca1 = df.loc[team1]['forca']
|
8 |
+
forca2 = df.loc[team2]['forca']
|
9 |
+
m = 2.25
|
10 |
+
lambda1 = m*forca1/(forca2 + forca1)
|
11 |
+
lambda2 = m - lambda1
|
12 |
+
|
13 |
+
return [lambda1, lambda2]
|
14 |
+
|
15 |
+
def resultado_vde(gols1, gols2):
|
16 |
+
|
17 |
+
if gols1 > gols2:
|
18 |
+
resultado = 'V'
|
19 |
+
elif gols1 < gols2:
|
20 |
+
resultado = 'D'
|
21 |
+
else:
|
22 |
+
resultado = 'E'
|
23 |
+
|
24 |
+
return resultado
|
25 |
+
|
26 |
+
|
27 |
+
def pontos_time(gols1, gols2):
|
28 |
+
|
29 |
+
resultado = resultado_vde(gols1, gols2)
|
30 |
+
if resultado == 'V':
|
31 |
+
pontos1, pontos2 = 3, 0
|
32 |
+
elif resultado == 'D':
|
33 |
+
pontos1, pontos2 = 0, 3
|
34 |
+
else:
|
35 |
+
pontos1, pontos2 = 0, 0
|
36 |
+
|
37 |
+
return [pontos1, pontos2, resultado]
|
38 |
+
|
39 |
+
def dist_poisson(media):
|
40 |
+
|
41 |
+
probs = [poisson.pmf(i, media) for i in range(0, 6, 1)] # calcula a probabilidade de sair i gols quando a média = media
|
42 |
+
probs.append(1-sum(probs)) # probabilidade de sair mais que 5 gols
|
43 |
+
return pd.Series(probs, index = ['0', '1', '2', '3', '4', '5', '6+'])
|
44 |
+
|
45 |
+
|
46 |
+
def probabilidades_partidas(df, team1, team2):
|
47 |
+
|
48 |
+
lambda1, lambda2 = lambda_(df, team1, team2)
|
49 |
+
dist1, dist2 = dist_poisson(lambda1), dist_poisson(lambda2)
|
50 |
+
matriz_resultados = np.outer(dist1, dist2) # outer produto dos valores de dist1 e dist2
|
51 |
+
|
52 |
+
# empates
|
53 |
+
empates = np.trace(matriz_resultados)
|
54 |
+
|
55 |
+
# soma dos triangulos inferiores
|
56 |
+
vitoria_team1 = np.tril(matriz_resultados).sum() - empates
|
57 |
+
|
58 |
+
# soma dos triangulos superiores
|
59 |
+
vitoria_team2 = np.triu(matriz_resultados).sum() - empates
|
60 |
+
|
61 |
+
vde = np.around([vitoria_team1, empates, vitoria_team2], 3)
|
62 |
+
probabilidades = [f'{100*i:.2f}%' for i in vde]
|
63 |
+
|
64 |
+
return probabilidades, 100*matriz_resultados
|
65 |
+
|
66 |
+
|
67 |
+
def simula_jogo(team1, team2):
|
68 |
+
|
69 |
+
lambda1, lambda2 = lambda_(team1, team2)
|
70 |
+
gols1 = int(np.random.poisson(lam=lambda1, size=1))
|
71 |
+
gols2 = int(np.random.poisson(lam=lambda2, size=1))
|
72 |
+
saldo1 = gols1 - gols2
|
73 |
+
saldo2 = gols2 - gols1
|
74 |
+
pts1, pts2, resultado = pontos_time(gols1, gols2)
|
75 |
+
placar = f'{gols1} X {gols2}'
|
76 |
+
|
77 |
+
return [gols1, gols2, saldo1, saldo2, pts1, pts2, resultado, placar]
|