Spaces:
Sleeping
Sleeping
| import streamlit as st | |
| import numpy as np | |
| import plotly.graph_objects as go | |
| import pandas as pd | |
| from PIL import Image | |
| #Criei uma função para repetir o HTML | |
| def html(conteudo): | |
| st.markdown(conteudo, unsafe_allow_html=True) | |
| st.markdown("### Simulação de Gols por Partida") | |
| html('<p>Um técnico de futebol quer entender a estatística por trás do campo e aumentar a efetividade do seu time</p>') | |
| html('<p>Para variar o esquema tático ele desenvolveu uma ferramenta para saber se precisa colocar em campo jogadores que vão conseguir produzir mais volume de jogo <b>(mais chutes ao gol)</b> ou um atacante mais efetivo, que aumentaria a <b> probabilidade de fazer o gol</b> </p>') | |
| html('<p>Com isso, desenvolveu a ferramenta utilizando a Distribuição Binomial. Ele já sabe que o seu time tem a probabilidade de fazer um gol por chute de 14%, ele quer saber qual esquema tático utilizar, enquanto o jogo acontece, variando os parâmetros que ele pode controlar; Como a quantidade de chutes que está dada ao gol.</p>') | |
| html('<p><li>Este parâmetro define o valor do número de chutes da partida</li></p>') | |
| numero_chutes_partida = st.slider("Chutes na Partida", 0, 30, 6) | |
| html('<p><li>Esta é a taxa de sucesso desse time fazer um gol</li></p>') | |
| probabilidade_gol = st.slider("Probabilidade de um Chute virar Gol em %", 0, 100, 14) | |
| html('<p><li>Quantas Simulações serão feitas</li></p>') | |
| simulacoes_monte_carlo = st.slider("Quantidade de Simulações - Monte Carlo", 1000, 100000, 5000) | |
| imagem = Image.open("src/binomial.png") | |
| st.image(imagem) | |
| html('<p>X = o número de Gols ou a variável aleatória; k = seria o valor de gols; n = o número total de chutes na partida; p a probabilidade desse chute virar gol;</p>') | |
| html('<p>(1-p) = probabilidade de errar o gol; (n/k) = numero de combinações possíveis de escolher (k) gols em (n) tentativas </p>') | |
| html('<p> Exemplo: n = 5, p = 0.2 e k = 2, o resultado é: 20,48% de chance de fazer exatamente 2 gols em 5 chutes</p>') | |
| html('<p>Por que usar a Binomial?</p>') | |
| html('<p>Com a simulação monte carlo e utilizando a Distribuição Binomial, o técnico vai saber a distribuição, tendo a ideia de quantos gols fará variando o seu esquema tático (afetando chutes e a probabilidade de fazer o gol)</p>') | |
| probabilidade_gol = (probabilidade_gol/100) | |
| simulacoes = np.random.binomial(numero_chutes_partida, probabilidade_gol, simulacoes_monte_carlo) | |
| if "params" not in st.session_state or st.session_state.params != ( | |
| numero_chutes_partida, | |
| probabilidade_gol, | |
| simulacoes_monte_carlo, | |
| ): | |
| st.session_state.simulacoes = np.random.binomial( | |
| numero_chutes_partida, probabilidade_gol, simulacoes_monte_carlo | |
| ) | |
| st.session_state.params = ( | |
| numero_chutes_partida, | |
| probabilidade_gol, | |
| simulacoes_monte_carlo, | |
| ) | |
| # Recupera as simulações salvas | |
| simulacoes = st.session_state.simulacoes | |
| html('<li>Abaixo uma tabela das distribuições com os parâmetros inseridos acima</li>') | |
| gols, numero_partidas = np.unique(simulacoes, return_counts=True) | |
| df = pd.DataFrame( | |
| { | |
| "Gols": [f"`{gol}`" for gol in gols], | |
| "Partidas": [f"**{partida}**" for partida in numero_partidas] | |
| } | |
| ) | |
| st.table(df) | |
| # Gráfico | |
| fig = go.Figure() | |
| fig.add_trace(go.Histogram( | |
| x=simulacoes, | |
| nbinsx=numero_chutes_partida+1, | |
| name='Distribuição de Gols', | |
| marker_color='green', | |
| opacity=0.75 | |
| )) | |
| fig.update_layout( | |
| title="Distribuição Simulada de Gols por Jogo", | |
| xaxis_title="Número de Gols em um Jogo", | |
| yaxis_title="Frequência", | |
| plot_bgcolor="white", | |
| bargap=0.05 | |
| ) | |
| st.plotly_chart(fig, use_container_width=True) | |
| html('<h4>Quantos chutes preciso fazer para vencer a partida.</h4>') | |
| #Outra simulação para descobrir quantos gols preciso fazer | |
| meta_gol = st.number_input("A Quantidade de Gols que você precisa",min_value=1,max_value=10,value=2) | |
| meta_gol = int(meta_gol) | |
| chutes_para_gol = meta_gol / probabilidade_gol | |
| numeros_possiveis = False ## Uma Flag para ver se é possível fazer essa quantidade gol com a probabilidade informada. | |
| for numero_chutes in range(1, 50): | |
| simulacoes2 = np.random.binomial(numero_chutes, probabilidade_gol, simulacoes_monte_carlo) | |
| media_total_gols = np.mean(simulacoes2) | |
| if media_total_gols >= meta_gol: | |
| st.write(f"Com {numero_chutes} chutes e probabilidade de {probabilidade_gol}%, você atinge em média {media_total_gols:.2f} gols.") | |
| numeros_possiveis = True | |
| break | |
| if numeros_possiveis == False: | |
| st.write("Não foi possível calcular a quantidade de gols necessárias, aumente a probabilidade") | |