Quebrando a banca com Python, Probabilidade e Estatística
Aprenda a criar um script para determinar a frequência em que números ocorrem numa jogatina
Uma boa dica para vencer os jogos de azar é basear-se em probabilidade. Mesmo sendo difícil de se entender e muitas das vezes indo na contramão das expectativas, a probabilidade é sem dúvida a sua melhor aposta. Ela pode ser utilizada nas atividades mais mundanas possíveis para prever a possibilidade de certos eventos virem a ocorrer ou não como a previsão do tempo, a bolsa de valores e a previsão do lance de cartas ou de dados.
No jogo Craps, por exemplo, que é muito popular em Cassinos, dois dados juntamente são lançados à sorte pelo shooter (jogador de dados) e a combinação de seus resultados determina um ponto. Se a soma de seus dados resultarem no ponto 7, dependendo do tipo de aposta, você pode faturar uma bolada. Porém, nem só de vitórias vive o homem: se o desfecho de um lançamento ou série de lançamentos de um jogador resultar em um ponto igual ou maior que 8, todos aqueles que apostaram suas fichas na perícia do shooter perdem.
Neste artigo, vamos simular a probabilidade da combinação de dois dados lançados sobre a mesa 11, 36, 360, 3600 e 36000 vezes. Como resultado teremos a frequência de cada face de um dado de seis lados (D6) mediante a repetição do nosso processo aleatório.
Como os dados funcionam
Quando dois dados D6 são lançados, em virtude da multiplicação de todas as possibilidades de cada um (D6 * D6), temos 36 combinações possíveis que se inicia em 2 (D6=1 + D6=1) e finaliza em 12 (D6=6 + D6=6).
A tabela que segue descreve de forma clara os resultados da soma de dois dados de seis lados para todas as 36 combinações: as colunas em tons únicos demonstram a soma do primeiro e do segundo dado de seis lados, já as colunas multicoloridas exibem o resultado da soma.
Note que o número sete é um curinga em jogos de lançamentos de dois dados D6. Ele é o mais frequente entre os demais e por isso tem maior probabilidade de ser sorteado. A soma do primeiro dado com o segundo pode resultar em 7 em seis diferentes situações: (1,6), (2,5), (3,4), (4,3), (5,2) e (6,1). Isso quer dizer que, mesmo se o primeiro dado lançado for 1, 2, 3,… ou 6, ainda há esperança de termos o 7 como resultado ao somar o segundo dado. Na verdade, nesta condição, temos uma chance em seis (16,7%). O mesmo não acontece nas mesmas circunstâncias para as demais faces do D6.
Modelo de probabilidade
A tabela a seguir descreve o modelo de probabilidade para a soma de dois dados de seis lados. Os números 2 e 12 são notavelmente as escolhas menos certeiras para se apostar visto que a probabilidade deles ocorrerem é de apenas uma a cada trinta e seis vezes. O 6, o 8 e principalmente o 7 são as escolhas mais certeiras.
Agora que já sabemos quais as regras estatísticas a que os dados se sujeitam, vamos testar na prática quando estes resultados ocorrem.
Rolando os dados
Analisar dados em sua forma mais bruta é uma tarefa fatigante. Imagine-se tendo agrupar os valores de milhares de dados lançados sobre uma mesa para responder “qual número é mais frequente?”, “qual o menos frequente?” ou “qual esta mais distante da média?”, seria penoso, não? Por sorte, existem ferramentas dedicadas a esta tarefa e que dispõe de gráficos exclusivos para o agrupamento de dados. Python juntamente com o módulo Pygal dão cabo do nosso problema com um pé nas costas. O código desenvolvido para este artigo é capaz de rodar um ou mais dados de n lados n vezes e retorna a frequência que os resultados aparecem além de suas estatísticas, entretanto, será testado apenas o lançamento de dois dados de seis lados por vez.
Este capítulo tem como finalidade apresentar o fluxo de trabalho que tratou da hipótese de que o número 7 é o mais frequente em jogos de azar de dois dados D6. Se você não deseja saber de como isso foi feito, se não se interessar pelo código em questão e sim pelo resultado final, pule para o próximo capítulo.
A Classe PyDice
Para conferir o código na integra, acesse o meu GitHub:
No código abaixo, é importante notar que o método __init__() recebe como argumento o total de lados dos dados que estarão em observação (sides), o total de dados que serão jogados por vez (dice) e a quantidade de vezes em que o jogador irá lançar estes dados.
Cada um dos argumentos recebidos são armazenados em seu respectivo atributo para serem utilizados nos métodos seguintes. Já os demais atributos foram inicializados com valor.
O método come_out_roll faz referência direta ao jogo Craps: após fazerem suas apostas, os jogadores torcem para o shooter que atira os dados sobre a mesa. O método come_out_roll utiliza o atributo shooter para decidir quantas vezes irá lançar os dados, o laço for, por sua vez, simula a quantidade de dados da mão do jogador. Os resultados são somados ainda dentro do laço for e só então armazenados em results.
A principal tarefa do método freq_dice é retornar a frequência que cada número ocorre na lista para a geração do gráfico de frequência. O resultado é armazenado na lista frequencies que é usada como variável de retorno.
Por fim, uma nova classe denominada DiceGraph foi criada, ela herda todos os métodos e atributos de PyDice. Note o seu método __init__(), assim como o da classe pai, a classe filha também possui os mesmos argumentos, contudo, os três argumentos possuem um valor default que será usado sempre que o usuário não os sobrescrever por meio de alguma variável.
Sempre que se cria uma instância de uma classe, o método __init__() é executado. Quando criarmos um objeto de DiceGraph, os métodos come_out_roll() e dice_freq(), da classe pai, serão executados e seus resultados armazenados em seus respectivos atributos (linhas 10 e 11). Uma linha adiante temos a criação do objeto chart que por sua vez herda todos os métodos e atributos da classe Bar().
O método dice_graphics utilizando-se dos recursos classe Bar() retorna um gráfico de barras (histograma). A legenda do gráfico foi estilizada com três dados estatístico: média, mediana e desvio padrão amostral.
O tipo de gráfico
O tipo de gráfico escolhido para a visualização dos dados foi o histograma, em consequência de suas características e da forma que ele trata e organiza grupos numéricos. O histograma produz gráficos que ilustram a base de dados em formatos reveladores: se o gráfico estiver pendendo para a direita, teremos uma média maior que a mediana e valores díspares na extremidade superior; do contrário, teremos uma média menor que a mediana e valores díspares na extremidade inferior. Portanto, se a ilustração apresentar uma forma senoidal, temos dados simétricos e a média e a mediana terão valores próximos.
Logo, o formato de ilustração ideal para os leitores deste artigo é o que tenha os dados simétricos e preferencialmente um alto valor de desvio padrão, isso porque, quanto maior for o desvio padrão, maior será a distância entre os grupos do histograma. Em outras palavras, se o nosso gráfico for bem equilibrado, mas com um alto desvio padrão, haverá grande diferença entre os valores dos resultados dos grupos e isso garantirá que o número centralizado no gráfico seja muito mais provável que os demais. Cabe lembrar que o desvio padrão utilizado aqui foi o amostral, pois a nossa população tende ao infinito.
O desvio padrão é uma maneira de se medir o quanto os números de um conjunto de dados variam, ele é a distância média da média.
Discutindo os resultados
Foi experimentando cinco diferentes iterações para simular o lançamento de dois dados de seis lados: 11, 36, 360 e 3600 e 36000. O primeiro teste, rolou o par de dados 11 vezes, garantindo assim, uma única chance para a ocorrência de cada um dos valores compreendidos entre 2 e 12. Abaixo você confere o resultado:
Como você pode ver, nem de longe o primeiro gráfico apresenta as estatísticas esperadas por todos nós, uma vez que o grupo 7 recebeu como resultado praticamente o dobro do que era previsto. Mas eu confesso que isso era esperado e se deve ao que podemos chamar de a lei da média: uma regra de estatística que diz que com o tempo os dados farão a média que se espera dos resultados, mas a curto prazo não se dá para prevê-los.
Podemos interpretar a probabilidade, no Gráfico 01, como uma mera possibilidade, por isso não se deve esperar confiante um 7 se jogarmos nosso par de dados apenas alguns punhados de vezes.
Com 36 rodadas o gráfico começa a tomar o aspecto de um sino, mas esta longe de retornar os resultados esperado. Ainda assim, observe no Gráfico 02 que o 7 passou certeiro no teste.
A partir de 360 rodadas, temos gráficos que refletem uma curva em forma de sino chegando a parecer uma pirâmide. Isso significa que os valores numéricos estão mais organizados, previsíveis e divididos em grupos de tamanho mais regular.
A probabilidade trabalha muito bem ao prever comportamentos a longo prazo e, e no caso acima, ela pode ser interpretada como porcentagem posto que os resultados tendem a variar bem menos. No gráfico onde os dados foram jogados 360 vezes, temos 8.92% de diferença entre o maior valor para o segundo maior valor e a possibilidade do resultado 7 ocorrer é de 16.9%. Já no gráfico à direita, onde os dados foram jogados 3600 vezes a diferença entre os dois maiores valores é de 17.6% e a possibilidade do 7 ocorrer é de 16.5%
Após 36000 rodadas os dados já estão praticamente “viciados” e os resultados podem facilmente ser previstos. A possibilidade de se obter um 7 após tantas tentativas é de 16,4%.
Frequência x Frequência
Você deve ter percebido que todos os gráficos até agora apresentam resultados relevantes para o nosso número 7. Isso se deve provavelmente a quantidade diminuta de testes que estamos aplicando aos nossos dados. Para reverter isso, vamos avaliar o resultados de uma forma mais trabalhosa. No Gráfico 05 temos um gráfico de pontos a esquerda e o de linhas a direita, que complementam o que vem sendo dito até aqui ao ilustrar a porcentagem de acerto entre os valores recebidos ao se jogar os dados com o valor esperado.
Cada circulo colorido do gráfico de pontos representa o lançamento de um par de dados 36, 360, 3600 ou 36000 vezes e este processo foi repetido dez vezes. O mesmo se fez para o gráfico de linhas, contudo o processo foi repetido 50 vezes. Então, fazendo as contas para o gráfico de pontos, o primeiro círculo somou 360 rodadas, e o ultimo círculo que começou com 36000, finalizou a décima rodada repetindo o processo 360000 vezes, já o gráfico de linhas, chegou a marca máxima de 1800000 rodadas. Haja braço!
Repare que além da cor, cada grupo de círculos ou de linhas possui um certo tamanho e comprimento, respectivamente, isso se deve a taxa entre o valor obtido ao jogar o dado e o esperado. Cada 36 rodadas espera-se que resulte em 6 valores iguais a 7 e a cada 36000 rodadas espera-se que resulte em 6000 valores iguais a 7. Em termos relativos, a porcentagem pode ser utilizada para mostrar quando um valor aumentou ou diminuiu e, quando foi jogado os 36 pares de dados dez vezes, no primeiro exemplo, a diferença entre os resultados recebidos para o esperado foi desmedida. O mesmo não aconteceu para o segundo círculos e tão pouco para os dois últimos que geraram gráficos mais simétricos e com resultados menos discrepantes.
Bônus
O Gráfico 06 evidencia que os dados já se sujeitam completamente a lei da média fazendo a média que se espera dos resultados. A diferença entre os dois maiores valores é de 19% e certamente isso não há de variar drasticamente como é no caso do primeiro e segundo gráfico.
Com um pouquinho de Python, probabilidade e estatística fomos capazes de prever o período aproximado onde os dados se tornam a média que se espera deles como resultado. Contudo, que fique bem claro que não existe receita de bolo para ficar rico em um Cassino, mas é possível utilizar estas informações para tomar alguma vantagem. Antes de encerrar este artigo, eu gostaria de escrever aqui mais duas dicas. A primeira é: saía do jogo enquanto estiver ganhando. E a segunda é: se você quer que seu dinheiro renda, dobre-o e guarde-o no bolso.