import pandas as pd
import numpy as np
import seaborn as sbn
import random
import matplotlib.pyplot as plt
from sklearn.preprocessing import MinMaxScaler
from scipy.stats import poisson
Nos dados a seguir teremos os pontos dos rankings das seleções e mais algumas informações.
selecoes = pd.read_excel('DadosCopaDoMundoQatar2022.xlsx', sheet_name='selecoes', index_col=0)
jogos = pd.read_excel('DadosCopaDoMundoQatar2022.xlsx', sheet_name='jogos')
selecoes.head()
Grupo | GrupoNumero | NomeEmIngles | PosiçãoRankingFIFA | ValorDeMercado | PontosRankingFIFA | PosiçãoEloRating | PontosEloRating | Confederação | Copas | JogadorDestaque | FotoJogadorDestaque | LinkBandeiraPequena | LinkBandeiraGrande | |
---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
Seleção | ||||||||||||||
Brasil | G | G1 | Brazil | 1 | 1090.0 | 1841 | 1 | 2185 | CONMEBOL | 5 | Neymar Jr. | https://github.com/ricardorocha86/PrevisaoEspo... | https://cloudinary.fifa.com/api/v3/picture/fla... | https://flagdownload.com/wp-content/uploads/Fl... |
Bélgica | F | F1 | Belgium | 2 | 559.0 | 1816 | 8 | 1948 | UEFA | 0 | Kevin De Bruyne | https://github.com/ricardorocha86/PrevisaoEspo... | https://cloudinary.fifa.com/api/v3/picture/fla... | https://flagdownload.com/wp-content/uploads/Fl... |
Argentina | C | C1 | Argentina | 3 | 608.0 | 1774 | 2 | 2101 | CONMEBOL | 2 | Lionel Messi | https://github.com/ricardorocha86/PrevisaoEspo... | https://cloudinary.fifa.com/api/v3/picture/fla... | https://flagdownload.com/wp-content/uploads/Fl... |
França | D | D1 | France | 4 | 886.0 | 1759 | 4 | 2046 | UEFA | 2 | Kylian Mbappé | https://github.com/ricardorocha86/PrevisaoEspo... | https://cloudinary.fifa.com/api/v3/picture/fla... | https://flagdownload.com/wp-content/uploads/Fl... |
Inglaterra | B | B1 | England | 5 | 1360.0 | 1728 | 10 | 1944 | UEFA | 1 | Harry Kane | https://github.com/ricardorocha86/PrevisaoEspo... | https://cloudinary.fifa.com/api/v3/picture/fla... | https://flagdownload.com/wp-content/uploads/Fl... |
Agora estamos gerando o fator de força para cada seleção, veja que nesse caso a seleção brasileira é considerada como a mais forte para a copa, em segunda posição vem a Argentina.
elorating = np.array(selecoes['PontosEloRating']).reshape(-1, 1)
MinMax = MinMaxScaler(feature_range=(0.15, 1))
newelorating = MinMax.fit_transform(elorating)
fifarating = np.array(selecoes['PontosRankingFIFA']).reshape(-1, 1)
newfifarating = MinMax.fit_transform(fifarating)
ref = (newelorating + newfifarating) / 2
selecoes["forca"] = ref
forca = selecoes["forca"]
forca
Seleção Brasil 1.000000 Bélgica 0.814346 Argentina 0.879044 França 0.827234 Inglaterra 0.728131 Espanha 0.792326 Holanda 0.758738 Portugal 0.723897 Dinamarca 0.658381 Alemanha 0.645253 México 0.545951 Uruguai 0.629086 Estados Unidos 0.540757 Croácia 0.650075 Suíça 0.617357 Senegal 0.445302 País de Gales 0.439271 Irã 0.480308 Marrocos 0.372767 Japão 0.463949 Sérvia 0.515573 Polônia 0.489044 Coreia do Sul 0.440537 Tunísia 0.347657 Costa Rica 0.390325 Camarões 0.263626 Austrália 0.356964 Canadá 0.343264 Equador 0.437371 Catar 0.211404 Arábia Saudita 0.259386 Gana 0.150000 Name: forca, dtype: float64
# Transformação Linear de Escala Numérica
#rat = selecoes["forca"]
#a, b = min(rat), max(rat)
#fa, fb = 0.15, 1
#b1 = (fb - fa)/(b-a)
#b0 = fb - b*b1
#forca = b0 + b1*rat
Abaixo geramos as funções para a distribuição da média de gols para cada seleção e obtenção, a partir de uma Poisson, um resultado aleatório de gols para a partida.
# Encontrando M1 e M2
def MediasPoisson(selecao1, selecao2, data=forca, mgols=2.5):
# Pegando do Dataframe a força de cada seleção
forca1 = forca[selecao1]
forca2 = forca[selecao2]
# Obtenção dos gols para o time 1
l1 = mgols*forca1/(forca1+forca2)
# Obtenção dos gols para o time 2
l2 = mgols - l1
# Retorno
return l1, l2
def Jogo(selecao1, selecao2):
# Pegando as médias de gols para cada seleção da função anterior
l1, l2 = MediasPoisson(selecao1, selecao2)
# Obtendo de uma Poisson um valor inteiro randômico para gols do time 1, a partir da sua média
gols1 = int(np.random.poisson(lam = l1, size=1))
# Obtendo de uma Poisson um valor inteiro randômico para gols do time 2, a partir da sua média
gols2 = int(np.random.poisson(lam = l2, size=1))
# Saldo de gols do time 1
saldo1 = gols1 - gols2
# Salo de gols do time 2
saldo2 = gols2 - gols1
# Obtenção da quantidade de Pontos para cada seleção
pontos1, pontos2, resultado = Pontos(gols1, gols2)
# Formato de exibição
placar = '{}x{}'.format(gols1, gols2)
# Retorno dos: gols, saldo, pontos e o placar
return [gols1, gols2, saldo1, saldo2, pontos1, pontos2, resultado, placar]
# FUNÇÕES AUXILIARES
def Resultado(gols1, gols2):
# Se o time 1 fez mais gols do que o time 2, então ele V = VENCEU
if gols1 > gols2:
resultado = 'V'
# Se o time 1 fez a mesma quantidade de gols do que o time 2, então ele E = Empatou
elif gols1 == gols2:
resultado = 'E'
# Se não aconteceu nenhum dos dois, ele perdeu
else:
resultado = 'D'
return resultado
def Pontos(gols1, gols2):
rst = Resultado(gols1, gols2)
# Se a saída da Função Resultado for vitória, o time 1 ganhou 3 pontos e o time 2 não ganhou nada
if rst == 'V':
pontos1, pontos2 = 3, 0
# Se a saída da Função Resultado for empate, o time 1 ganhou 1 pontos e o time 2 ganhou 1
if rst == 'E':
pontos1, pontos2 = 1, 1
# Se a saída da Função Resultado for derrota, o time 1 ganhou 0 pontos e o time 2 ganhou 3
if rst == 'D':
pontos1, pontos2 = 0, 3
return [pontos1, pontos2, rst]
# É por meio dessa diferença de forças que os placares se diferenciam para cada partida.
# No caso abaixo, 1,33 gols foram para o Brasil e 1,17 foram para a Argentina, somando dá 2,5
print('Brasil x Argentina')
print(MediasPoisson('Brasil', 'Argentina'))
# No caso abaixo, 0,81 gols foram para o Catar e 1,69 foram para o Equador, somando dá 2,5
print('Catar x Equador')
print(MediasPoisson('Catar', 'Equador'))
Brasil x Argentina (1.3304636235252418, 1.1695363764747582) Catar x Equador (0.8146267153322221, 1.685373284667778)
# Simulando um Jogo entre Brasil e Argentina
sim1 = Jogo('Brasil', 'Argentina')
print("Gols do Brasil:", sim1[0])
print("Gols da Argentina:", sim1[1])
print("Saldo de Gols do Brasil:", sim1[2])
print("Saldo de Gols da Argentina:", sim1[3])
print("Pontos Brasil:", sim1[4])
print("Pontos Argentina:", sim1[5])
print("Brasil venceu, empatou ou perdeu?", sim1[6])
print("Placar da Partida:", sim1[7])
Gols do Brasil: 1 Gols da Argentina: 1 Saldo de Gols do Brasil: 0 Saldo de Gols da Argentina: 0 Pontos Brasil: 1 Pontos Argentina: 1 Brasil venceu, empatou ou perdeu? E Placar da Partida: 1x1
Veja que cada vez que a função for rodada ela gera novos placares. Pois, a partir da distribuição de probabilidade, gera valores possíveis.
Essa função gera o resultado para um Jogo somente, temos agora que rodar essa função infinitas vezes para ver quais resultados mais ocorreriam. Assim, temos as probabilidades de cada resultado e, como consequência, o resultado mais provável e improvável para a partida.
def Distribuicao(media):
# Lista para colocarmos as probabilidade
probs = []
# Executar a função de Poisson para a média de gols do time até x = 7.
for i in range(7):
probs.append(poisson.pmf(i, media))
# Obtendo a probabilidade da quantidade de gols ser maior ou igual a 7
probs.append(1 - sum(probs))
# Retorno das probabilidades
return pd.Series(probs, index=['0', '1', '2', '3', '4', '5', '6', '7+'])
def ProbabilidadesPartidas(selecao1, selecao2):
# Gerando a média para cada seleção
l1, l2 = MediasPoisson(selecao1, selecao2)
# Usando a função anterior para gerar a distribuição de probabilidade
d1, d2 = Distribuicao(l1), Distribuicao(l2)
# Gerando uma matriz da multiplicação das probabilidades
matriz = np.outer(d1, d2)
# Somando o triangulo inferior para a probabilidade de vitória do time 1
vitoria = np.tril(matriz).sum() - np.trace(matriz) #Soma o triâgulo inferior
# Somando o triângulo superior para a probabilidade de derrota do time 1
derrota = np.triu(matriz).sum() - np.trace(matriz) #Soma o triângulo superior
# Obtedo a probabilidade de empate
empate = 1 - (vitoria + derrota)
# Arredondando para 3 casas decimais e definindo o padrão de porcentagem
probs = np.around([vitoria, empate, derrota], 3)
probsp = [f'{100*i:.1f}%' for i in probs]
# Transformando a matriz de multiplicação em um dataframe e modificando os nomes dos indices e das colunas
nomes = ['0', '1', '2', '3', '4', '5', '6', '7+']
matriz = pd.DataFrame(matriz, columns=nomes, index=nomes)
matriz.index = pd.MultiIndex.from_product([[selecao1], matriz.index])
matriz.columns = pd.MultiIndex.from_product([[selecao2], matriz.columns])
# Saída da função um dicionário
output = {
'seleção1': selecao1,
'seleção2': selecao2,
'f1': forca[selecao1],
'f2': forca[selecao2],
'media1': l1,
'media2': l2,
'probabilidades': probsp,
'matriz': matriz
}
return output
def GerarHeatmap(selecao1, selecao2):
tab = ProbabilidadesPartidas(selecao1, selecao2)
fig, ax = plt.subplots(figsize=(15,6))
ax = sbn.heatmap(tab['matriz'], fmt=".5f", annot=True, cmap="crest", ax=ax,
yticklabels=[0, 1, 2, 3, 4, 5, 6, "7+"], xticklabels=[0, 1, 2, 3, 4, 5, 6, "7+"])
ax.set_title("Probabilidade: " + tab["seleção1"] + " x " + tab["seleção2"], fontsize=25, pad=25)
ax.set_xlabel(tab["seleção2"], fontsize=16, labelpad=15, loc='left')
ax.set_ylabel(tab["seleção1"], fontsize=16, labelpad=15, loc='top')
ax.xaxis.set_label_position("top")
ax.xaxis.tick_top()
plt.xticks(fontsize="14")
plt.yticks(fontsize="14")
return plt.show()
# Gerando as probabilidades dos resultados para um Jogo entre Brasil e Argentina
ProbabilidadesPartidas('Brasil', 'Argentina')
{'seleção1': 'Brasil', 'seleção2': 'Argentina', 'f1': 1.0, 'f2': 0.879044233750574, 'media1': 1.3304636235252418, 'media2': 1.1695363764747582, 'probabilidades': ['40.4%', '26.9%', '32.7%'], 'matriz': Argentina \ 0 1 2 3 4 5 Brasil 0 0.082085 0.096001 0.056139 0.021885 0.006399 0.001497 1 0.109211 0.127726 0.074690 0.029118 0.008514 0.001991 2 0.072651 0.084968 0.049686 0.019370 0.005663 0.001325 3 0.032220 0.037682 0.022035 0.008590 0.002512 0.000588 4 0.010717 0.012534 0.007329 0.002857 0.000835 0.000195 5 0.002852 0.003335 0.001950 0.000760 0.000222 0.000052 6 0.000632 0.000740 0.000432 0.000169 0.000049 0.000012 7+ 0.000144 0.000168 0.000098 0.000038 0.000011 0.000003 6 7+ Brasil 0 2.917519e-04 5.691812e-05 1 3.881653e-04 7.572749e-05 2 2.582199e-04 5.037634e-05 3 1.145174e-04 2.234129e-05 4 3.809031e-05 7.431070e-06 5 1.013555e-05 1.977354e-06 6 2.247498e-06 4.384662e-07 7+ 5.103050e-07 9.955583e-08 }
GerarHeatmap("Brasil", "França")
jogos['Vitória'] = None
jogos['Empate'] = None
jogos['Derrota'] = None
for i in range(jogos.shape[0]):
selecao1 = jogos['seleção1'][i]
selecao2 = jogos['seleção2'][i]
v, e, d = ProbabilidadesPartidas(selecao1, selecao2)['probabilidades']
jogos.at[i, 'Vitória'] = v
jogos.at[i, 'Derrota'] = d
jogos.at[i, 'Empate'] = e
jogos
data | hora | grupo | seleção1 | seleção2 | estádio | Vitória | Empate | Derrota | |
---|---|---|---|---|---|---|---|---|---|
0 | 2022-11-21 | 07:00:00 | A | Senegal | Holanda | AL THUMAMA | 22.1% | 25.3% | 52.6% |
1 | 2022-11-21 | 13:00:00 | A | Catar | Equador | AL KHOR | 17.9% | 24.0% | 58.1% |
2 | 2022-11-25 | 10:00:00 | A | Catar | Senegal | AL THUMAMA | 17.6% | 23.9% | 58.6% |
3 | 2022-11-25 | 13:00:00 | A | Holanda | Equador | INTER. KHALIFA | 53.1% | 25.2% | 21.7% |
4 | 2022-11-29 | 12:00:00 | A | Holanda | Catar | AL KHOR | 71.1% | 19.6% | 9.4% |
5 | 2022-11-29 | 12:00:00 | A | Equador | Senegal | INTER. KHALIFA | 36.0% | 27.0% | 37.0% |
6 | 2022-11-21 | 10:00:00 | B | Inglaterra | Irã | INTER. KHALIFA | 49.1% | 25.9% | 25.0% |
7 | 2022-11-21 | 16:00:00 | B | Estados Unidos | País de Gales | AL RAYYAN | 42.8% | 26.7% | 30.5% |
8 | 2022-11-25 | 07:00:00 | B | País de Gales | Irã | AL RAYYAN | 33.9% | 27.0% | 39.2% |
9 | 2022-11-25 | 16:00:00 | B | Inglaterra | Estados Unidos | AL KHOR | 45.5% | 26.4% | 28.0% |
10 | 2022-11-29 | 16:00:00 | B | País de Gales | Inglaterra | AL RAYYAN | 22.8% | 25.5% | 51.8% |
11 | 2022-11-29 | 16:00:00 | B | Irã | Estados Unidos | AL THUMAMA | 33.0% | 26.9% | 40.1% |
12 | 2022-11-22 | 07:00:00 | C | Argentina | Arábia Saudita | CID. EDUCAÇÃO | 69.9% | 20.0% | 10.0% |
13 | 2022-11-22 | 13:00:00 | C | México | Polônia | AL WAKRAH | 39.8% | 26.9% | 33.3% |
14 | 2022-11-26 | 10:00:00 | C | Polônia | Arábia Saudita | CID. EDUCAÇÃO | 55.5% | 24.6% | 19.9% |
15 | 2022-11-26 | 16:00:00 | C | Argentina | México | NAC. DE LUSAIL | 50.9% | 25.6% | 23.5% |
16 | 2022-11-30 | 16:00:00 | C | Polônia | Argentina | PORTO DE DOHA | 20.9% | 25.0% | 54.1% |
17 | 2022-11-30 | 16:00:00 | C | Arábia Saudita | México | NAC. DE LUSAIL | 17.6% | 23.9% | 58.6% |
18 | 2022-11-22 | 10:00:00 | D | Dinamarca | Tunísia | CID. EDUCAÇÃO | 55.6% | 24.6% | 19.8% |
19 | 2022-11-22 | 16:00:00 | D | França | Austrália | AL WAKRAH | 61.1% | 23.1% | 15.8% |
20 | 2022-11-26 | 07:00:00 | D | Tunísia | Austrália | AL WAKRAH | 35.7% | 27.0% | 37.3% |
21 | 2022-11-26 | 13:00:00 | D | França | Dinamarca | PORTO DE DOHA | 43.4% | 26.7% | 29.9% |
22 | 2022-11-30 | 12:00:00 | D | Tunísia | França | CID. EDUCAÇÃO | 15.3% | 22.9% | 61.8% |
23 | 2022-11-30 | 12:00:00 | D | Austrália | Dinamarca | AL WAKRAH | 20.3% | 24.8% | 54.9% |
24 | 2022-11-23 | 10:00:00 | E | Alemanha | Japão | INTER. KHALIFA | 46.5% | 26.3% | 27.2% |
25 | 2022-11-23 | 13:00:00 | E | Espanha | Costa Rica | AL THUMAMA | 57.6% | 24.1% | 18.3% |
26 | 2022-11-27 | 07:00:00 | E | Japão | Costa Rica | AL RAYYAN | 41.7% | 26.8% | 31.5% |
27 | 2022-11-27 | 16:00:00 | E | Espanha | Alemanha | AL KHOR | 42.7% | 26.7% | 30.6% |
28 | 2022-12-01 | 16:00:00 | E | Japão | Espanha | INTER. KHALIFA | 22.1% | 25.3% | 52.6% |
29 | 2022-12-01 | 16:00:00 | E | Costa Rica | Alemanha | AL KHOR | 22.8% | 25.5% | 51.7% |
30 | 2022-11-23 | 07:00:00 | F | Marrocos | Croácia | AL KHOR | 21.6% | 25.2% | 53.3% |
31 | 2022-11-23 | 16:00:00 | F | Bélgica | Canadá | AL RAYYAN | 61.7% | 22.9% | 15.3% |
32 | 2022-11-27 | 10:00:00 | F | Bélgica | Marrocos | AL THUMAMA | 59.6% | 23.6% | 16.9% |
33 | 2022-11-27 | 13:00:00 | F | Croácia | Canadá | INTE. KHALIFA | 55.6% | 24.6% | 19.8% |
34 | 2022-12-01 | 12:00:00 | F | Croácia | Bélgica | AL RAYYAN | 30.0% | 26.7% | 43.3% |
35 | 2022-12-01 | 12:00:00 | F | Canadá | Marrocos | AL THUMAMA | 34.1% | 27.0% | 39.0% |
36 | 2022-11-24 | 07:00:00 | G | Suíça | Camarões | AL WAKRAH | 61.4% | 23.0% | 15.6% |
37 | 2022-11-24 | 16:00:00 | G | Brasil | Sérvia | NAC. LUSAIL | 56.3% | 24.5% | 19.3% |
38 | 2022-11-28 | 07:00:00 | G | Camarões | Sérvia | AL WAKRAH | 19.1% | 24.4% | 56.5% |
39 | 2022-11-28 | 13:00:00 | G | Brasil | Suíça | PORTO DE DOHA | 51.1% | 25.6% | 23.3% |
40 | 2022-12-02 | 16:00:00 | G | Camarões | Brasil | NAC. LUSAIL | 8.7% | 19.1% | 72.1% |
41 | 2022-12-02 | 16:00:00 | G | Sérvia | Suíça | PORTO DE DOHA | 31.3% | 26.8% | 41.9% |
42 | 2022-11-24 | 10:00:00 | H | Uruguai | Coreia do Sul | CID. EDUCAÇÃO | 47.3% | 26.2% | 26.5% |
43 | 2022-11-24 | 13:00:00 | H | Portugal | Gana | PORTO DE DOHA | 76.2% | 17.3% | 6.5% |
44 | 2022-11-28 | 10:00:00 | H | Coreia do Sul | Gana | CID. EDUCAÇÃO | 66.9% | 21.2% | 11.9% |
45 | 2022-11-28 | 16:00:00 | H | Portugal | Uruguai | NAC. LUSAIL | 40.7% | 26.9% | 32.4% |
46 | 2022-12-02 | 12:00:00 | H | Coreia do Sul | Portugal | CID. EDUCAÇÃO | 23.0% | 25.5% | 51.5% |
47 | 2022-12-02 | 12:00:00 | H | Gana | Uruguai | AL WAKRAH | 7.7% | 18.3% | 73.9% |
Vamos salvar essa tabel em excel para que possamos fazer representações visuais em outros frameworks.
# Gravando os resultados em um arquivo excel.
jogos.to_excel('estimativasJogosCopa.xlsx')
# Função para simular um grupo
def JogosGrupo(dados, grupo):
# Selecionamos um grupo e obtemos somente os times que fazem parte dele
times = list(dados[dados['Grupo'] == grupo].index)
time1, time2, time3, time4 = times
# Simulamos todos os possíveis confrontos e dele obtemos os resultado, saldo de gols e etc.
jogo1 = Jogo(time1, time2)
jogo2 = Jogo(time3, time4)
jogo3 = Jogo(time1, time3)
jogo4 = Jogo(time2, time4)
jogo5 = Jogo(time1, time4)
jogo6 = Jogo(time2, time3)
# Criando variáveis vazias para irmos preenchendo conforme os jogos acontecem
pt1, pt2, pt3, pt4 = 0, 0, 0, 0
gp1, gp2, gp3, gp4 = 0, 0, 0, 0
sg1, sg2, sg3, sg4 = 0, 0, 0, 0
# Preenchemos para o confronto 1 as variáveis
gp1, gp2, sg1, sg2, pt1, pt2 = gp1 + jogo1[0], gp2 + jogo1[1], sg1 + jogo1[2], sg2 + jogo1[3], pt1 + jogo1[4], pt2 + jogo1[5]
# Preenchemos para o confronto 2 as variáveis
gp3, gp4, sg3, sg4, pt3, pt4 = gp3 + jogo2[0], gp4 + jogo2[1], sg3 + jogo2[2], sg4 + jogo2[3], pt3 + jogo2[4], pt4 + jogo2[5]
# Preenchemos para o confronto 3 as variáveis
gp1, gp3, sg1, sg3, pt1, pt3 = gp1 + jogo3[0], gp3 + jogo3[1], sg1 + jogo3[2], sg3 + jogo3[3], pt1 + jogo3[4], pt3 + jogo3[5]
# Preenchemos para o confronto 4 as variáveis
gp2, gp4, sg2, sg4, pt2, pt4 = gp2 + jogo4[0], gp4 + jogo4[1], sg2 + jogo4[2], sg4 + jogo4[3], pt2 + jogo4[4], pt4 + jogo4[5]
# Preenchemos para o confronto 5 as variáveis
gp1, gp4, sg1, sg4, pt1, pt4 = gp1 + jogo5[0], gp4 + jogo5[1], sg1 + jogo5[2], sg4 + jogo5[3], pt1 + jogo5[4], pt4 + jogo5[5]
# Preenchemos para o confronto 6 as variáveis
gp2, gp3, sg2, sg3, pt2, pt3 = gp2 + jogo6[0], gp3 + jogo6[1], sg2 + jogo6[2], sg3 + jogo6[3], pt2 + jogo6[4], pt3 + jogo6[5]
# Juntamos tudo em um Dataframe unificado, com uma coluna para os pontos, uma para o saldo de gols e uma para gols prós
# Colocamos como índices o nome das variáveis e os nomes dos times
tab = pd.DataFrame([[pt1, pt2, pt3, pt4], [sg1, sg2, sg3, sg4], [gp1, gp2, gp3, gp3]],
columns=[time1, time2, time3, time4],
index = ['Pontos', 'Saldo de Gols', 'Gols Pró']).T
# Ordenamos primeiro pelo Pontos, Depois pelo Saldo de Gols e por fim pelos Gols Pró. E ordenamos do maior para o menor.
tab = tab.sort_values(by = ['Pontos', 'Saldo de Gols', 'Gols Pró'], ascending=False)
tab['Posição'] = [1, 2, 3, 4]
# Nome dos times em cada Partida
partidas = [
time1 + ' x ' + time2,
time3 + ' x ' + time4,
time1 + ' x ' + time3,
time2 + ' x ' + time4,
time1 + ' x ' + time4,
time2 + ' x ' + time3,
]
# Resultado de cada jogo
resultados = [jogo1[6], jogo2[6], jogo3[6], jogo4[6], jogo5[6], jogo6[6]]
# Plcar dos jogos
placares = [jogo1[-1], jogo2[-1], jogo3[-1], jogo4[-1], jogo5[-1], jogo6[-1]]
# Criando um Dataframe unificado dos resultados acima
jogos = pd.DataFrame([partidas, placares, resultados]).transpose()
jogos.columns = ['Partidas', 'Placar', 'Resultado']
# Retornamos uma lista dos dois Dataframes criados
return [tab, jogos]
def JogoMataMata(selecao1, selecao2):
# Simula um jogo entre duas seleções
jogo = Jogo(selecao1, selecao2)
# Gravando o resultado do jogo
resultado = jogo[6]
# Se a seleção1 venceu, ela é retornada na função e passa de fase
if resultado == 'V':
return selecao1
# Se a seleção 1 perdeu, então quem passa é a seleção2, ela será retornada pela função
elif resultado == 'D':
return selecao2
# Caso ocorra empate, a escolha será randomica entre elas
else:
return random.sample([selecao1, selecao2], 1)[0]
Com todas as funções construídas, podemos unificar tudo em somente uma função Geral e simular uma copa como um todo.
# Função Para Simular uma Copa
def SimulaCopa(selecoes):
# Nome das Colunas será as fases
cols = ['1st', '2sd', '3rd', '4th', 'Oitavas', 'Quartas', 'Semis', 'Final', 'Campeão']
# Coletamos a quantidadde de seleções
n = selecoes.shape[0]
# A quantidade de fases
m = len(cols)
# 1 - Cria-se um array de 0, na quantidade de fases * número de seleções
# 2 - Reorganiza para que cada lista (9) conte com 47 zeros (número de seleções)
# 3 - Iremos Transformar em um DataFrame e transformar em valores inteiros
# 4 - Esse DataFrame será utilizado para preenchimento de 0 se o time não ficou naquela posição (1 ou 2 ou 3 ou 4 do grupo)
# ou 1 se ficou. E coloca 0 se náo alcançou aquela fase (oitavas, quartas, semis ou final) ou 1 se alcançou.
aux = np.array(np.zeros(n*m).reshape(n, m))
info = pd.DataFrame(aux, columns=cols, index=selecoes.index)
info = info.astype(int)
# As oitavas contam com 16 times, temos que pegar esses times que passaram de fase, simulando os grupos iremos ober a
# posição de cada time no grupo e em seguida procurar eles em nosso Dataframe e adicionar o valor 1 para a posição que
# o time ficou no grupo.
top16 = []
# Para cada grupo
for i in list('ABCDEFGH'):
#Simular as partidas e pegar a tabela
a = JogosGrupo(selecoes, grupo = i)[0]
a.index[:2].tolist()
# Adicionando os 2 primeiros em uma lista dos que passaram para a outra fase
top16 += a.index[:2].tolist()
# Pegando todas as seleções
anomes = a.index.tolist()
# Atribuindo ao que ficou na primeira posição o valor 1 na coluna de primeira colocação
# A pesquia é feita por meio do nome na seleção no índice
info.at[anomes[0], '1st'] = 1
# Atribuindo ao que ficou na segunda posição o valor 1 na coluna de segunda colocação
info.at[anomes[1], '2sd'] = 1
# Atribuindo ao que ficou na terceira posição posição o valor 1 na coluna de terceira colocação
info.at[anomes[2], '3rd'] = 1
# Atribuindo ao que ficou na quarta posição o valor 1 na coluna de primeira colocação colocação
info.at[anomes[3], '4th'] = 1
# Simula as chaves das oitavas e coleta os ganhadores
qf1 = JogoMataMata(top16[0], top16[3])
qf2 = JogoMataMata(top16[2], top16[1])
qf3 = JogoMataMata(top16[4], top16[7])
qf4 = JogoMataMata(top16[6], top16[5])
qf5 = JogoMataMata(top16[8], top16[11])
qf6 = JogoMataMata(top16[10], top16[9])
qf7 = JogoMataMata(top16[12], top16[15])
qf8 = JogoMataMata(top16[14], top16[13])
# Adiciona os ganhadores em uma lista para as quartas
top8 = [qf1, qf2, qf3, qf4, qf5, qf6, qf7, qf8]
# Simula a chave das quartas
sf1 = JogoMataMata(top8[0], top8[3])
sf2 = JogoMataMata(top8[2], top8[1])
sf3 = JogoMataMata(top8[4], top8[7])
sf4 = JogoMataMata(top8[6], top8[5])
# Adiciona os ganhadores das quartas em uma lista para as semis
top4 = [sf1, sf2, sf3, sf4]
# Simula os jogos das Semis
f1 = JogoMataMata(sf1, sf3)
f2 = JogoMataMata(sf2, sf4)
# Adiciona para a final
top2 = [f1, f2]
# Simula o jogo da fina
top1 = JogoMataMata(f1, f2)
# Na tabela procura cada time e adiciona o 1 a eles nas colunas referentes
info.loc[top16, 'Oitavas'] = 1
info.loc[top8, 'Quartas'] = 1
info.loc[top4, 'Semis'] = 1
info.loc[top2, 'Final'] = 1
info.loc[top1, 'Campeão'] = 1
# Retorna o Dataframe com os valores
return info
Agora podemos simular uma copa apenas, para obter o resultado. Cada vez que for rodado, pode ser que um novo campeão seja dado. No caso abaixo foi a seleção da França.
SimulaCopa(selecoes=selecoes)
1st | 2sd | 3rd | 4th | Oitavas | Quartas | Semis | Final | Campeão | |
---|---|---|---|---|---|---|---|---|---|
Seleção | |||||||||
Brasil | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
Bélgica | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 1 |
Argentina | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
França | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 |
Inglaterra | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |
Espanha | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
Holanda | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
Portugal | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 0 |
Dinamarca | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
Alemanha | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
México | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
Uruguai | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 |
Estados Unidos | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 0 |
Croácia | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 |
Suíça | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
Senegal | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
País de Gales | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
Irã | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
Marrocos | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
Japão | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
Sérvia | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
Polônia | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 |
Coreia do Sul | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
Tunísia | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
Costa Rica | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
Camarões | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
Austrália | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
Canadá | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
Equador | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
Catar | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
Arábia Saudita | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
Gana | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
Agora foi a seleção da Belgica:
SimulaCopa(selecoes=selecoes)
1st | 2sd | 3rd | 4th | Oitavas | Quartas | Semis | Final | Campeão | |
---|---|---|---|---|---|---|---|---|---|
Seleção | |||||||||
Brasil | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 |
Bélgica | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 0 | 0 |
Argentina | 1 | 0 | 0 | 0 | 1 | 1 | 1 | 1 | 1 |
França | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
Inglaterra | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 0 | 0 |
Espanha | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
Holanda | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
Portugal | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
Dinamarca | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 |
Alemanha | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
México | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
Uruguai | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
Estados Unidos | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
Croácia | 0 | 1 | 0 | 0 | 1 | 1 | 1 | 1 | 0 |
Suíça | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
Senegal | 1 | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
País de Gales | 1 | 0 | 0 | 0 | 1 | 1 | 0 | 0 | 0 |
Irã | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
Marrocos | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
Japão | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
Sérvia | 0 | 1 | 0 | 0 | 1 | 1 | 0 | 0 | 0 |
Polônia | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
Coreia do Sul | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
Tunísia | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
Costa Rica | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
Camarões | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
Austrália | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 | 0 |
Canadá | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
Equador | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
Catar | 0 | 1 | 0 | 0 | 1 | 0 | 0 | 0 | 0 |
Arábia Saudita | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
Gana | 0 | 0 | 0 | 1 | 0 | 0 | 0 | 0 | 0 |
Isso quer dizer que qualquer seleção pode ser campeã?
Teoricamente sim pois, mesmo que mínima a probabilidade, pode acontecer.
Por isso, para prever a probabilidade de cada seleção ser campeã poderíamos rodar esse código infinitas vezes e verificar de qual valor cada probabilidade de campeã se aproximar cada seleção. Como isso requer uma capacidade computacional enorme, teremos que definir um valor suficientemente grande.
Rodarei para um valor de 10 mil simulações.
def SimulacaoTotal(dados, S = 1000):
# Exibimos uma mensagem para o usuário saber que está começando o modelo
print('IA: "Iniciando Simulação..."')
# Simulamos uma primeira copa e colocamos o Dataframe na variável info
info = SimulaCopa(selecoes)
# Rodaremos esse código para S-1 vezes definida, pois a primeira já foi rodada acima.
for i in range(S - 1):
# Cada iteração irá somar o valor da posição anterior
info += SimulaCopa(selecoes)
# Para cada resto inteiro da décima parte iremos exibir na tela o progresso
if (i+2)%(S/10) == 0:
print('IA: Simulação de Copa do Mundo: {:.0f}% completas'.format(100*((i+2)/S)))
# Após roda todas as iterações exibimos que acabou.
print('IA: "Simulação Finalizada!"')
# Retornamos um dataframe rankeado pela coluna campeão e dividimos os valores pela quantidade de iteração para obtermos as
# probabilidades
return info.sort_values(by = 'Campeão', ascending=False)/S
# Rodando para 10000 iterações
S = 10000
sim = SimulacaoTotal(selecoes, S)
sim.to_excel('outputSimulacoesCopadoMundo.xlsx')
sim
IA: "Iniciando Simulação..." IA: Simulação de Copa do Mundo: 10% completas IA: Simulação de Copa do Mundo: 20% completas IA: Simulação de Copa do Mundo: 30% completas IA: Simulação de Copa do Mundo: 40% completas IA: Simulação de Copa do Mundo: 50% completas IA: Simulação de Copa do Mundo: 60% completas IA: Simulação de Copa do Mundo: 70% completas IA: Simulação de Copa do Mundo: 80% completas IA: Simulação de Copa do Mundo: 90% completas IA: Simulação de Copa do Mundo: 100% completas IA: "Simulação Finalizada!"
1st | 2sd | 3rd | 4th | Oitavas | Quartas | Semis | Final | Campeão | |
---|---|---|---|---|---|---|---|---|---|
Seleção | |||||||||
Brasil | 0.5660 | 0.2637 | 0.1283 | 0.0420 | 0.8297 | 0.5382 | 0.3353 | 0.2084 | 0.1291 |
Argentina | 0.5390 | 0.2668 | 0.1416 | 0.0526 | 0.8058 | 0.4941 | 0.3032 | 0.1696 | 0.0995 |
França | 0.4938 | 0.2917 | 0.1425 | 0.0720 | 0.7855 | 0.4639 | 0.2772 | 0.1512 | 0.0835 |
Bélgica | 0.4825 | 0.2957 | 0.1480 | 0.0738 | 0.7782 | 0.4619 | 0.2521 | 0.1412 | 0.0771 |
Holanda | 0.5574 | 0.2617 | 0.1351 | 0.0458 | 0.8191 | 0.4850 | 0.2683 | 0.1412 | 0.0730 |
Espanha | 0.4590 | 0.2767 | 0.1679 | 0.0964 | 0.7357 | 0.4271 | 0.2337 | 0.1294 | 0.0668 |
Portugal | 0.4575 | 0.3198 | 0.1804 | 0.0423 | 0.7773 | 0.4109 | 0.2243 | 0.1203 | 0.0586 |
Inglaterra | 0.4188 | 0.2722 | 0.1839 | 0.1251 | 0.6910 | 0.4112 | 0.2213 | 0.1178 | 0.0578 |
Dinamarca | 0.3341 | 0.3415 | 0.2013 | 0.1231 | 0.6756 | 0.3485 | 0.1866 | 0.0916 | 0.0443 |
Croácia | 0.3360 | 0.3353 | 0.2087 | 0.1200 | 0.6713 | 0.3509 | 0.1702 | 0.0870 | 0.0412 |
Uruguai | 0.3471 | 0.3495 | 0.2449 | 0.0585 | 0.6966 | 0.3314 | 0.1627 | 0.0823 | 0.0377 |
Alemanha | 0.3000 | 0.3072 | 0.2323 | 0.1605 | 0.6072 | 0.3145 | 0.1543 | 0.0735 | 0.0361 |
Suíça | 0.2379 | 0.3491 | 0.2766 | 0.1364 | 0.5870 | 0.2936 | 0.1440 | 0.0699 | 0.0326 |
Estados Unidos | 0.2396 | 0.2808 | 0.2495 | 0.2301 | 0.5204 | 0.2707 | 0.1218 | 0.0531 | 0.0238 |
México | 0.2312 | 0.3294 | 0.2796 | 0.1598 | 0.5606 | 0.2532 | 0.1232 | 0.0509 | 0.0218 |
Sérvia | 0.1703 | 0.2896 | 0.3509 | 0.1892 | 0.4599 | 0.2065 | 0.0894 | 0.0405 | 0.0190 |
Polônia | 0.1882 | 0.2923 | 0.3297 | 0.1898 | 0.4805 | 0.2117 | 0.0980 | 0.0378 | 0.0142 |
Irã | 0.1816 | 0.2259 | 0.2879 | 0.3046 | 0.4075 | 0.1965 | 0.0811 | 0.0343 | 0.0140 |
Senegal | 0.2082 | 0.3297 | 0.2991 | 0.1630 | 0.5379 | 0.2233 | 0.0877 | 0.0336 | 0.0116 |
Equador | 0.2019 | 0.3064 | 0.3169 | 0.1748 | 0.5083 | 0.2126 | 0.0814 | 0.0277 | 0.0107 |
País de Gales | 0.1600 | 0.2211 | 0.2787 | 0.3402 | 0.3811 | 0.1685 | 0.0632 | 0.0242 | 0.0094 |
Coreia do Sul | 0.1839 | 0.2842 | 0.4031 | 0.1288 | 0.4681 | 0.1773 | 0.0661 | 0.0250 | 0.0090 |
Japão | 0.1468 | 0.2332 | 0.3071 | 0.3129 | 0.3800 | 0.1543 | 0.0610 | 0.0254 | 0.0087 |
Costa Rica | 0.0942 | 0.1829 | 0.2927 | 0.4302 | 0.2771 | 0.1003 | 0.0367 | 0.0133 | 0.0048 |
Marrocos | 0.1032 | 0.2003 | 0.3301 | 0.3664 | 0.3035 | 0.1068 | 0.0346 | 0.0133 | 0.0041 |
Austrália | 0.0867 | 0.1805 | 0.3249 | 0.4079 | 0.2672 | 0.0955 | 0.0372 | 0.0116 | 0.0037 |
Canadá | 0.0783 | 0.1687 | 0.3132 | 0.4398 | 0.2470 | 0.0842 | 0.0263 | 0.0079 | 0.0030 |
Tunísia | 0.0854 | 0.1863 | 0.3313 | 0.3970 | 0.2717 | 0.0909 | 0.0320 | 0.0100 | 0.0027 |
Arábia Saudita | 0.0416 | 0.1115 | 0.2491 | 0.5978 | 0.1531 | 0.0422 | 0.0111 | 0.0028 | 0.0010 |
Camarões | 0.0258 | 0.0976 | 0.2442 | 0.6324 | 0.1234 | 0.0331 | 0.0086 | 0.0040 | 0.0008 |
Catar | 0.0325 | 0.1022 | 0.2489 | 0.6164 | 0.1347 | 0.0322 | 0.0067 | 0.0011 | 0.0003 |
Gana | 0.0115 | 0.0465 | 0.1716 | 0.7704 | 0.0580 | 0.0090 | 0.0007 | 0.0001 | 0.0001 |
Nosso modelo previu que a o Brasil é a seleção com a maior probabilidade de ser campeão da competição.
Por fim, apenas fazemos manipulações com os valores para retornar a: probabilidade de cada seleção cair em cada fase e a probabilidade de cada seleção avançar para cada fase.
etapas = pd.DataFrame()
etapas['Cair na 1º Fase'] = 1 - sim['Oitavas']
etapas['Cair nas Oitavas'] = sim['Oitavas'] - sim['Quartas']
etapas['Cair nas Quartas'] = sim['Quartas'] - sim['Semis']
etapas['Cair nas Semis'] = sim['Semis'] - sim['Final']
etapas['Cair nas Final'] = sim['Final'] - sim['Campeão']
etapas['Ganhar a Final'] = sim['Campeão']
etapas.to_excel('outputProbabilidadesPorEtapa.xlsx')
etapas
Cair na 1º Fase | Cair nas Oitavas | Cair nas Quartas | Cair nas Semis | Cair nas Final | Ganhar a Final | |
---|---|---|---|---|---|---|
Seleção | ||||||
Brasil | 0.1703 | 0.2915 | 0.2029 | 0.1269 | 0.0793 | 0.1291 |
Argentina | 0.1942 | 0.3117 | 0.1909 | 0.1336 | 0.0701 | 0.0995 |
França | 0.2145 | 0.3216 | 0.1867 | 0.1260 | 0.0677 | 0.0835 |
Bélgica | 0.2218 | 0.3163 | 0.2098 | 0.1109 | 0.0641 | 0.0771 |
Holanda | 0.1809 | 0.3341 | 0.2167 | 0.1271 | 0.0682 | 0.0730 |
Espanha | 0.2643 | 0.3086 | 0.1934 | 0.1043 | 0.0626 | 0.0668 |
Portugal | 0.2227 | 0.3664 | 0.1866 | 0.1040 | 0.0617 | 0.0586 |
Inglaterra | 0.3090 | 0.2798 | 0.1899 | 0.1035 | 0.0600 | 0.0578 |
Dinamarca | 0.3244 | 0.3271 | 0.1619 | 0.0950 | 0.0473 | 0.0443 |
Croácia | 0.3287 | 0.3204 | 0.1807 | 0.0832 | 0.0458 | 0.0412 |
Uruguai | 0.3034 | 0.3652 | 0.1687 | 0.0804 | 0.0446 | 0.0377 |
Alemanha | 0.3928 | 0.2927 | 0.1602 | 0.0808 | 0.0374 | 0.0361 |
Suíça | 0.4130 | 0.2934 | 0.1496 | 0.0741 | 0.0373 | 0.0326 |
Estados Unidos | 0.4796 | 0.2497 | 0.1489 | 0.0687 | 0.0293 | 0.0238 |
México | 0.4394 | 0.3074 | 0.1300 | 0.0723 | 0.0291 | 0.0218 |
Sérvia | 0.5401 | 0.2534 | 0.1171 | 0.0489 | 0.0215 | 0.0190 |
Polônia | 0.5195 | 0.2688 | 0.1137 | 0.0602 | 0.0236 | 0.0142 |
Irã | 0.5925 | 0.2110 | 0.1154 | 0.0468 | 0.0203 | 0.0140 |
Senegal | 0.4621 | 0.3146 | 0.1356 | 0.0541 | 0.0220 | 0.0116 |
Equador | 0.4917 | 0.2957 | 0.1312 | 0.0537 | 0.0170 | 0.0107 |
País de Gales | 0.6189 | 0.2126 | 0.1053 | 0.0390 | 0.0148 | 0.0094 |
Coreia do Sul | 0.5319 | 0.2908 | 0.1112 | 0.0411 | 0.0160 | 0.0090 |
Japão | 0.6200 | 0.2257 | 0.0933 | 0.0356 | 0.0167 | 0.0087 |
Costa Rica | 0.7229 | 0.1768 | 0.0636 | 0.0234 | 0.0085 | 0.0048 |
Marrocos | 0.6965 | 0.1967 | 0.0722 | 0.0213 | 0.0092 | 0.0041 |
Austrália | 0.7328 | 0.1717 | 0.0583 | 0.0256 | 0.0079 | 0.0037 |
Canadá | 0.7530 | 0.1628 | 0.0579 | 0.0184 | 0.0049 | 0.0030 |
Tunísia | 0.7283 | 0.1808 | 0.0589 | 0.0220 | 0.0073 | 0.0027 |
Arábia Saudita | 0.8469 | 0.1109 | 0.0311 | 0.0083 | 0.0018 | 0.0010 |
Camarões | 0.8766 | 0.0903 | 0.0245 | 0.0046 | 0.0032 | 0.0008 |
Catar | 0.8653 | 0.1025 | 0.0255 | 0.0056 | 0.0008 | 0.0003 |
Gana | 0.9420 | 0.0490 | 0.0083 | 0.0006 | 0.0000 | 0.0001 |
avanco = pd.DataFrame()
avanco['Avançar na 1ª Fase'] = sim['Oitavas']
avanco['Avançar nas Oitavas'] = sim['Quartas']/sim['Oitavas']
avanco['Avançar nas Quartas'] = sim['Semis']/sim['Quartas']
avanco['Avançar nas Semis'] = sim['Final']/sim['Semis']
avanco['Avançar na Final'] = sim['Campeão']/sim['Final']
avanco.to_excel('outputAvancoPorEtapa.xlsx')
avanco
Avançar na 1ª Fase | Avançar nas Oitavas | Avançar nas Quartas | Avançar nas Semis | Avançar na Final | |
---|---|---|---|---|---|
Seleção | |||||
Brasil | 0.8297 | 0.648668 | 0.623003 | 0.621533 | 0.619482 |
Argentina | 0.8058 | 0.613179 | 0.613641 | 0.559367 | 0.586675 |
França | 0.7855 | 0.590579 | 0.597543 | 0.545455 | 0.552249 |
Bélgica | 0.7782 | 0.593549 | 0.545789 | 0.560095 | 0.546034 |
Holanda | 0.8191 | 0.592113 | 0.553196 | 0.526277 | 0.516997 |
Espanha | 0.7357 | 0.580536 | 0.547179 | 0.553701 | 0.516229 |
Portugal | 0.7773 | 0.528625 | 0.545875 | 0.536335 | 0.487116 |
Inglaterra | 0.6910 | 0.595080 | 0.538181 | 0.532309 | 0.490662 |
Dinamarca | 0.6756 | 0.515838 | 0.535438 | 0.490890 | 0.483624 |
Croácia | 0.6713 | 0.522717 | 0.485038 | 0.511163 | 0.473563 |
Uruguai | 0.6966 | 0.475739 | 0.490947 | 0.505839 | 0.458080 |
Alemanha | 0.6072 | 0.517951 | 0.490620 | 0.476345 | 0.491156 |
Suíça | 0.5870 | 0.500170 | 0.490463 | 0.485417 | 0.466381 |
Estados Unidos | 0.5204 | 0.520177 | 0.449945 | 0.435961 | 0.448211 |
México | 0.5606 | 0.451659 | 0.486572 | 0.413149 | 0.428291 |
Sérvia | 0.4599 | 0.449011 | 0.432930 | 0.453020 | 0.469136 |
Polônia | 0.4805 | 0.440583 | 0.462919 | 0.385714 | 0.375661 |
Irã | 0.4075 | 0.482209 | 0.412723 | 0.422935 | 0.408163 |
Senegal | 0.5379 | 0.415133 | 0.392745 | 0.383124 | 0.345238 |
Equador | 0.5083 | 0.418257 | 0.382879 | 0.340295 | 0.386282 |
País de Gales | 0.3811 | 0.442141 | 0.375074 | 0.382911 | 0.388430 |
Coreia do Sul | 0.4681 | 0.378765 | 0.372814 | 0.378215 | 0.360000 |
Japão | 0.3800 | 0.406053 | 0.395334 | 0.416393 | 0.342520 |
Costa Rica | 0.2771 | 0.361963 | 0.365902 | 0.362398 | 0.360902 |
Marrocos | 0.3035 | 0.351895 | 0.323970 | 0.384393 | 0.308271 |
Austrália | 0.2672 | 0.357410 | 0.389529 | 0.311828 | 0.318966 |
Canadá | 0.2470 | 0.340891 | 0.312352 | 0.300380 | 0.379747 |
Tunísia | 0.2717 | 0.334560 | 0.352035 | 0.312500 | 0.270000 |
Arábia Saudita | 0.1531 | 0.275637 | 0.263033 | 0.252252 | 0.357143 |
Camarões | 0.1234 | 0.268233 | 0.259819 | 0.465116 | 0.200000 |
Catar | 0.1347 | 0.239050 | 0.208075 | 0.164179 | 0.272727 |
Gana | 0.0580 | 0.155172 | 0.077778 | 0.142857 | 1.000000 |
Junto a esse projeto foram criados dois Dashboards: um em Power BI e outro com o Streamlit. Para acessa-los basta clicar no desejado.