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('

Um técnico de futebol quer entender a estatística por trás do campo e aumentar a efetividade do seu time

') html('

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 (mais chutes ao gol) ou um atacante mais efetivo, que aumentaria a probabilidade de fazer o gol

') html('

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.

') html('

  • Este parâmetro define o valor do número de chutes da partida
  • ') numero_chutes_partida = st.slider("Chutes na Partida", 0, 30, 6) html('

  • Esta é a taxa de sucesso desse time fazer um gol
  • ') probabilidade_gol = st.slider("Probabilidade de um Chute virar Gol em %", 0, 100, 14) html('

  • Quantas Simulações serão feitas
  • ') simulacoes_monte_carlo = st.slider("Quantidade de Simulações - Monte Carlo", 1000, 100000, 5000) imagem = Image.open("src/binomial.png") st.image(imagem) html('

    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;

    ') html('

    (1-p) = probabilidade de errar o gol; (n/k) = numero de combinações possíveis de escolher (k) gols em (n) tentativas

    ') html('

    Exemplo: n = 5, p = 0.2 e k = 2, o resultado é: 20,48% de chance de fazer exatamente 2 gols em 5 chutes

    ') html('

    Por que usar a Binomial?

    ') html('

    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)

    ') 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('
  • Abaixo uma tabela das distribuições com os parâmetros inseridos acima
  • ') 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('

    Quantos chutes preciso fazer para vencer a partida.

    ') #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")