PETRUS ROMANUS
LEI DOS GRANDES NÚMEROS
A Lei dos Grandes Números é muito importante no mundo dos negócios. Para ilustrar de um modo muito simples, imagine que você jogue uma moeda 2 vezes, várias vezes, e anote os resultados: apesar de sabermos que a probabilidade de dar cara (ou coroa) seja de 50%, jogando apenas duas vezes, em boa parte dos casos, essa probabilidade não ocorrerá (haverá muitos 100% contra 0%); quando você aumenta o número de jogadas, digamos para 10, começa a haver uma tendência para que os 50% sejam atingidos com maior precisão (dificilmente, em 10 lançamentos, você verá 100% de caras e 0% de coroas, por exemplo). Ainda assim, 10 lançamentos é pouco... A Lei dos Grandes Números afirma que, quanto mais lançamentos você fizer, mais os valores obtidos tendem a se aproximar da porcentagem esperada. Para ilustrar essa situação, eu programei no Blender a simulação abaixo utilizando Geometry Nodes e outras ferramentas do referido programa:

Observe que as duas barras vão se nivelando (em 50%) conforme o número de jogadas aumenta. Utilizei um gerador de números aleatórios para a simulação ser condizente com a realidade
É a Lei dos Grandes Números que prediz, por exemplo, o lucro de um cassino (ou outro jogo de azar) ao longo do tempo com alto grau de certeza. Portanto, trago aqui, em Python, algumas simulações referentes a esse campo de estudos tão interessante. Abaixo, temos um primeiro código que explorará a situação das moedas mostrada acima.
import pylab
import random
qtd = 1000
cara = 0
coroa = 0
x = []
y_cara =[]
y_coroa = []
for i in range (1,qtd+1):
a = random.randint(0,1)
if a == 0:
cara += 1
elif a == 1:
coroa += 1
x.append(i)
y_cara.append(cara/i)
y_coroa.append(coroa/i)
pylab.axis([0,qtd,0,1])
pylab.plot(x,y_cara,"b")
pylab.plot(x,y_coroa,"r")
pylab.show()
A variável "qtd" recebe a quantidade de lançamentos. Abaixo, podemos ver diversos gráficos gerados com diversos valores diferentes para "qtd". As linhas, claro, representarão 50% se estiverem no meio (na marca de 0,5).

10 lançamentos

50 lançamentos

100 lançamentos

5000 lançamentos

10 lançamentos

50 lançamentos

100 lançamentos

5000 lançamentos
Observe nos diversos gráficos o que já pôde ter sido conferido no vídeo: a convergência para 50%. Abaixo, um último gráfico representando 100 mil lançamentos:

Já o código abaixo nos permite fazer outro tipo de simulação: imagine um jogo de sorteio com bolas numeradas de 1 até 20. Caso saia de 0 até 9, o jogador ganha; caso saia de 10 até 20, a banca ganha. Essa pequena probabilidade a mais da banca ganhar, em poucas partidas, não é significativa. No entanto, o programa permite que façamos muitas simulações para um número alto de partidas (que é quando veremos a Lei dos Grandes Números em ação, sendo a vitória, quase sempre, da banca).
import pylab
import random
qtd = 500
jogador = 0
banca = 0
x = []
y_jog =[]
y_ban = []
for i in range (1,qtd+1):
a = random.randint(0,20)
if a >= 0 and a < 10:
jogador += 1
elif a >= 10 and a <= 20:
banca += 1
x.append(i)
y_jog.append(jogador/i)
y_ban.append(banca/i)
pylab.axis([0,qtd,0,1])
pylab.plot(x,y_jog,"b")
pylab.plot(x,y_ban,"r")
pylab.show()
Para poucas partidas, é normal o jogador ganhar da banca. Mas quando executamos o código acima do jeito que está, ou seja, para 500 partidas, é quase certeza a banca ganhar:

O jogador é representado pela cor azul: apenas nos primeiros jogos ele teve algum ganho
E para aprofundar mais ainda, fiquei curioso sobre o cenário acima: e se eu repetisse a simulação acima 100, 200, 500 vezes, como seriam os resultados? Para tanto (é claro que eu não ia executar o programa 500 vezes para depois analisar todos os gráficos), criei este outro código:
import random
blocos = 365 #qtd de repetições
qtd = 500 #qtd de jogos
banca = 0
jogador = 0
resultado = []
banca_vit = 0
jogador_vit = 0
empate = 0
for bloco in range (blocos):
for i in range (1,qtd+1):
a = random.randint(0,20)
if a >= 0 and a < 10:
jogador += 1
elif a >= 10 and a <= 20:
banca += 1
resultado.append(banca)
resultado.append(jogador)
if banca > jogador:
banca_vit += 1
elif banca < jogador:
jogador_vit += 1
else:
empate += 1
banca = 0
jogador = 0
for i in range (0, blocos*2, 2):
print("Banca %d x %d Jogador" %(resultado[i],resultado[i+1]))
print("")
print("Vitórias da banca: %d" %(banca_vit))
print("Vitórias do jogador: %d" %(jogador_vit))
print("Empates: %d" %(empate))
Executando o código acima uma vez, ou seja, 500 blocos de partidas sendo repetidos 365 vezes:

Ou seja, 311 vitórias para a banca, 45 para o jogador e 9 empates.
Ao colocar 5000 jogos, numa última simulação que fiz aqui, a banca ganhou todas as 365 vezes.