Programei duas distribuições matematicas — Binomial e Normal — em Go com o intuito de utilizar programação para reforçar o entendimento da matemática.

Longe de ser sobre data science esse texto é sobre um tempo que tive pra mim e que dediquei a visitar temas que gosto.

Vamos lá conversar sobre matemática e programação.

O início da jornada Matemática

Tudo começa com o NNT — o Nassim Nicholas Taleb — de quem sou fã desde a leitura do Cisne Negro.
Foi durante uma leitura do Iludidos pelo Acaso, A influência da sorte nos mercados e na vida que me peguei preso a maneira como o Taleb faz uso de simulações de Monte Carlo.

A maneira Talebiana de escrever torna o assunto divertido.

“O nome Monte Carlo traz à mente a imagem de um homem urbano bronzeado do tipo europlayboy entrando em um cassino em meio à brisa mediterranea. Ele sabe esquiar e jogar tenis, mas tambem se garante no xadrez e no bridge. Tem um carro esportivo cinza, usa ternos italianos feitos sob medida e bem passados, e fala com cuidado e suavidade sobre assuntos mundamos e reais, que um jornalista poderia facilmente descrever ao público em frases curtas. Dentro do cassino, ele conta as cartas com astúcia, calcula as probabilidades e aposta de maneira estudada, sua mente produzindo calulos precisos da aposta perfeita. Poderia ser o irmão perdido e mais esperto de James Bond.
Quando penso no método de Monter Carlo, penso alegremente em uma combinação de ambas as coisas: o realismo do homem de Monte Carlo, sem a superficialidade, misturado com a intuição do matemático, sem a abstração excessiva.”

Nesse ponto eu admito, I’m hooked! E se passaram dias de viagens de metro e trem para o trabalho seguindo esse fluxo de consciencia do Taleb.

Foi isso que me levou ao exercício provavel da probabilidade na programação.

O Hook

NNT se diverte durante o livro com seus brinquedos baseados em Monte Carlo e eu também quero me divertir 🙂

Não é incomum ouvir de um programador que vai utilizar Monte Carlo quando o que quer dizer é que vai usar aleatoriedade para testar um software em um cenário incerto ou talvez não tão incerto assim. (As vezes a dificuldade de coletar uma amostra significativa dentre toda a população de logs leva ao uso de Monte Carlo sem levar em conta que o resultado é diferente).

Usar uma amostra dos logs é olhar o que já aconteceu enquanto Monte Carlo ajuda a simular o que pode acontecer.

Monte Carlo é usado para resolver problemas deterministicos através de estatística para obter resposta numéricas para problemas que talvez sejam difíceis de resolver de forma analítica. Numa simplificação, da pra dizer que é usar aleatoriedade para gerar entradas(amostra) para um sistema com o objetivo de entender seu comportamento de um ponto de vista probabilistico .

Cara ou Coroa

Foi esse jogo, o cara ou coroa, que me levou as distribuições matemáticas.

O jogo de cara ou coroa é comum quando se fala de Monte Carlo por que ele tem input aleatório e permite inferir a probabilidade de eventos, que é a combinação de resultado. É um ponto de partida classico.

Existe 50% de chance de cair cara ou coroa ao jogar uma vez a moeda, mas qual a chance de 3 caras se eu jogar 5 vezes? Essa é a pergunta interessante que o Monte Carlo ajuda a responder.

qual a chance de 3 caras se eu jogar 5 vezes?

Podemos obter o resultado através do método analitico(matematica).

Fórmula: P(X = k) = ( n ) . p^k . q^(n-k)
( k )
Onde:
n = 5 (total) p = 0,5 (sucesso)
k = 3 (desejado) q = 0,5 (fracasso)

1) Coeficiente Binomial (5 / 3):
5! / 3!(5-3)! = (5.4.3!) / (3!.2.1) = 20/2 = 10

2) Potências:
(0,5)³ = 0,125
(0,5)² = 0,25

3) Resultado:
P(X=3) = 10 . 0,125 . 0,25
P(X=3) = 0,3125

ou podemos estimar uma resposta usando o método computacional de Monte Carlos como no código em Go no link flipCoin3on5.go (veja os exemplos de execução abaixo)

Obs.: O código abaixo não passou por qualquer otimização. Uma outra versão com atomics e goroutines que pode ser vista em flipCoin3on5_bignumbers.go e mesmo essa otimização não exaure as possibilidades de melhoria de performance.

#Poucas Rodadas não trazem uma boa estimativa, por exemplo, com 1 rodada ou srá Probabilidade de 0% ou de 100%.

./flipCoin3on5 1
Simulou 1 rodadas de 5 lançamentos...
Casos com exatamente 3 caras: 0
Probabilidade Estimada: 0.0000 (0.00%)

./flipCoin3on5 1
Simulou 1 rodadas de 5 lançamentos...
Casos com exatamente 3 caras: 1
Probabilidade Estimada: 1.0000 (100.00%)

#Com uma quantidade de Rodadas insuficiente o dado não é confiavel.
./flipCoin3on5 50
Casos com exatamente 3 caras: 17
Probabilidade Estimada: 0.3400 (34.00%)

./flipCoin3on5 50
Casos com exatamente 3 caras: 17
Probabilidade Estimada: 0.3400 (34.00%)

#Com rodadas demais temos uma ótima estimativa mas desperdiçamos tempo.
# 1 Bilhão rodadas => 1 minuto
time ./flipCoin3on5 1000000000   
Simulou 1000000000 rodadas de 5 lançamentos...
Casos com exatamente 3 caras: 312500797
Probabilidade Estimada: 0.3125 (31.25%)
real    1m8,066s
user    1m8,147s
sys    0m0,080s

#Com rodas o suficiente temos uma ótima estimativa 
#com 8/10 execuções com Probabilidade estimativa identica a Probabilidade teórica.
# Duzentos Milhões de rodadas => 13 sec
time ./flipCoin3on5 200000000 
Simulou 200000000 rodadas de 5 lançamentos...
Casos com exatamente 3 caras: 62506172
Probabilidade Estimada: 0.3125 (31.25%)
real    0m13,721s
user    0m13,732s
sys    0m0,012s

time ./flipCoin3on5 200000000
Simulou 200000000 rodadas de 5 lançamentos...
Casos com exatamente 3 caras: 62489409
Probabilidade Estimada: 0.3124 (31.24%)
real    0m13,547s
user    0m13,557s
sys    0m0,024s

Alguns Pontos interessantes até aqui:

  • Um evento é uma combinação de resultados(ex.:ocorrer 3 caras em 5 jogadas).
  • Na simulação tivemos evidencia de um teorema fundamenta da probabilidade, a lei dos grandes números.
  • A simulação provou uma probabilidade teórica calculada, e ainda fica a pergunta: Como teriamos certeza da assertividade da resposta se não tivessemos a probabilidade teórica calculada?
  • A Jogo de cara ou coroa utiliza distribuição Binomial na solução analitica e vou falar dela próximo artigo.
  • O jogo de cara ou coroa traz outro tema interessante. A falácia do Apostador
  • O exemplo de Monte Carlo utilizado é simples. Monte Carlo é um método para obter aproximações numéricas de funções complexas e as vezes impossíveis de se obter resultados de maneira determinística. Vou voltar ao Monte Carlo com exemplos mais interesantes.

Além das médias

Aplicar probabilidade à tecnologia ajuda a trazer mais segurança na tomada de decisões que vão desde a aprovação de uma nova tela de checkout(um teste A/B), um novo endpoint de API(teste de carga) e passam por tratamento de ruido em dados como dados de GPS(reflexões de sinal). Eu pretendo visitar esses casos nos próximos textos.

O que vem a Seguir?

Aqui eu contei que durante as realização desse exercícios inspirados pelo NNT acabei me interessando ainda mais por distribuições matemáticas e decidindo implementar primeiro a Binomial, por que ela aparece no exercício de jogar moedas e depois pela distribuição Normal que tem uma relação direta com o que vimos até aqui.

O repositório dessas implementações é o godist e vou falar sobre ele no artigo sobre distribuição binomial.

Como próximo artigo acho interessante abordar a seguinte questão: Como ter certeza da assertividade da resposta da simulação sem comparar com probabilidade teórica?

Godist no github: https://github.com/iannsp/godist