Capítulo 9.3
Índice
- 1. O que é Ciência de Dados?
- 2. Causalidade e Experimentos
- 3. Progamando em Python
- 4. Tipos de Dados
- 5. Sequências
- 6. Tabelas
- 7. Visualização
- 8. Funções e Tabelas
- 9. Aleatoriedade
- 10. Amostragem e Distribuições Empíricas
- 11. Testando Hipóteses
- 12. Comparando Duas Amostras
- 13. Estimação
- 14. Por que a Média é Importante
- 15. Previsão
from datascience import *
path_data = '../../../assets/data/'
import matplotlib
matplotlib.use('Agg')
%matplotlib inline
import matplotlib.pyplot as plots
plots.style.use('fivethirtyeight')
import numpy as np
Simulação
A simulação é o processo de usar um computador para imitar um experimento físico. Nesta disciplina, esses experimentos quase invariavelmente envolverão o acaso.
Vimos como simular os resultados de lançamentos de uma moeda. Os passos dessa simulação foram exemplos dos passos que constituirão cada simulação que faremos neste curso. Nesta seção, vamos estabelecer esses passos e segui-los em exemplos.
O Processo
Passo 1: O Que Simular
Decida qual quantidade você deseja simular. Por exemplo, você pode decidir que deseja simular os resultados dos lançamentos de uma moeda. Cada valor simulado será uma Cara ou uma Coroa.
Passo 2: Simulando Um Valor
Descubra como simular um valor da quantidade especificada no Passo 1. Em nosso exemplo, você precisa descobrir como simular o resultado de um lançamento de uma moeda. Se sua quantidade for mais complicada, talvez você precise de várias linhas de código para obter um valor simulado. Tipicamente, definiremos uma função que retorna o valor simulado.
Passo 3: Número de Repetições
Decida quantas vezes você deseja simular a quantidade. Você terá que repetir a simulação no Passo 2 tantas vezes. Em um de nossos exemplos anteriores, decidimos simular os resultados de 1000 lançamentos de uma moeda, então precisamos de 1000 repetições para gerar o resultado de um único lançamento.
Passo 4: Simulando Múltiplos Valores
Finalmente, coloque tudo junto da seguinte maneira.
- Crie uma matriz vazia na qual coletará todos os valores simulados. Chamaremos isso de matriz de coleção.
- Crie uma “sequência de repetições,” ou seja, uma sequência cujo comprimento é o número de repetições especificado no Passo 3. Para
nrepetições, quase sempre usaremos a sequêncianp.arange(n). - Crie um loop
for. Para cada elemento da sequência de repetições:- Simule um valor usando a função que você escreveu no Passo 2.
- Acrescente a matriz de coleção com este valor simulado.
Isso é tudo! Uma vez que você tenha realizado os passos acima, sua simulação está pronta. A matriz de coleção contém todos os valores simulados.
Neste ponto, você pode usar a matriz de coleção como faria com qualquer outra matriz. Você pode contar quantos valores simulados caem em uma categoria específica, colocar a matriz na coluna de uma tabela e visualizar a distribuição dos valores simulados, e assim por diante.
Exemplo: Número de Caras em 100 Lançamentos
É natural esperar que em 100 lançamentos de uma moeda, haverá 50 caras, com algumas variações.
Mas quantas são “algumas”? Qual é a chance de obter exatamente 50 caras? Questões como essas são importantes na ciência de dados não apenas porque são sobre aspectos interessantes de aleatoriedade, mas também porque podem ser usadas na análise de experimentos nos quais as atribuições aos grupos de tratamento e controle são decididas pelo lançamento de uma moeda.
Neste exemplo, vamos simular o número de caras em 100 lançamentos de uma moeda. O histograma de nossos resultados nos dará algumas ideias sobre quantas caras são prováveis.
Vamos começar a simulação, seguindo as etapas acima.
Etapa 1: O que Simular
A quantidade que vamos simular é o número de caras em 100 lançamentos.
Etapa 2: Simulando Um Valor
Temos que descobrir como fazer um conjunto de 100 lançamentos e contar o número de caras. Vamos começar criando uma moeda.
coin = make_array('Heads', 'Tails')
Em nosso exemplo anterior, usamos np.random.choice e um loop for para gerar vários lançamentos. Mas conjuntos de lançamentos de moeda são necessários com tanta frequência na ciência de dados que np.random.choice os simula para nós se incluímos um segundo argumento que é o número de vezes que deve ser lançado.
Aqui estão os resultados de 10 lançamentos.
ten_tosses = np.random.choice(coin, 10)
ten_tosses
| Out[1]: | array([‘Heads’, ‘Tails’, ‘Heads’, ‘Tails’, ‘Tails’, ‘Heads’, ‘Tails’, ‘Tails’, ‘Tails’, ‘Heads’], dtype='<U5′) |
Podemos contar o número de caras usando np.count_nonzero como antes:
np.count_nonzero(ten_tosses == 'Heads')
| Out[2]: | 4 |
Nosso objetivo é simular o número de caras em 100 lançamentos, e não 10. Para fazer isso podemos simplesmente repetir o mesmo código, substituindo 10 por 100.
outcomes = np.random.choice(coin, 100)
num_heads = np.count_nonzero(outcomes == 'Heads')
num_heads
| Out[3]: | 46 |
Como queremos fazer isso várias vezes, vamos definir uma função que retorne o valor simulado do número de caras. Podemos fazer isso usando o código desenvolvido na célula acima.
def one_simulated_value():
outcomes = np.random.choice(coin, 100)
return np.count_nonzero(outcomes == 'Heads')
Etapa 3: Número de Repetições
Quantas repetições vamos usar depende de nós. Quanto mais usarmos, mais confiáveis serão nossas simulações, mas mais tempo levará para executar o código. O Python é bastante rápido para lançar moedas, então vamos para 20.000 repetições. Isso significa que vamos fazer o seguinte 20.000 vezes:
- Lançar uma moeda 100 vezes e contar o número de caras.
Isso é muitos lançamentos! É bom que tenhamos o Python para fazer isso por nós.
Etapa 4: Simulando Múltiplos Valores
Estamos prontos para criar uma matriz de 20.000 valores simulados do número de caras em 100 lançamentos de uma moeda.
num_repetitions = 20000 # número de repetições
heads = make_array() # array vazio
for i in np.arange(num_repetitions): # repita o processo num_repetitions vezes
new_value = one_simulated_value() # simular um valor usando a função definida
heads = np.append(heads, new_value) # aumente a matriz da coleção com o valor simulado
# É isso! A simulação está feita.
Verifique se a matriz heads contém 20.000 entradas, uma para cada repetição do experimento.
len(heads)
| Out[4]: | 20000 |
Para ter uma noção da variabilidade no número de caras em 100 lançamentos, podemos reunir os resultados numa tabela e desenhar um histograma.
simulation_results = Table().with_columns(
'Repetition', np.arange(1, num_repetitions + 1),
'Number of Heads', heads
)
simulation_results.show(3)
| Repetition | Number of Heads |
|---|---|
| 1 | 44 |
| 2 | 54 |
| 3 | 44 |
simulation_results.hist('Number of Heads', bins = np.arange(30.5, 69.6, 1))

Cada intervalo tem largura 1 e está centrado em cada valor do número de caras.
Não é surpreendente que o histograma pareça aproximadamente simétrico em torno de 50 caras. A altura da barra em 50 é cerca de 8% por unidade. Como cada intervalo tem largura 1 unidade, isso significa que cerca de 8% das repetições produziram exatamente 50 caras. Não é uma porcentagem enorme, mas é a maior em comparação com a porcentagem em cada outro número de caras.
O histograma também mostra que em quase todas as repetições, o número de caras em 100 lançamentos estava entre 35 e 65. De fato, a maioria das repetições produziu números de caras no intervalo de 45 a 55.
Embora teoricamente seja possível que o número de caras possa estar em qualquer lugar entre 0 e 100, a simulação mostra que o intervalo de valores prováveis é muito menor.
Este é um exemplo de um fenômeno mais geral sobre a variabilidade no lançamento de moedas, como veremos mais adiante no curso.
Exemplo: Movimentos no Monopoly
Cada movimento no jogo Monopoly é determinado pelo número total de casas de dois lançamentos de um dado. Se você jogar Monopoly, o que deve esperar obter quando lançar o dado duas vezes?
Podemos explorar isso simulando a soma de dois lançamentos de um dado. Vamos executar a simulação 10.000 vezes. Observe que neste parágrafo concluímos as Etapas 1 e 3 do nosso processo de simulação.
A Etapa 2 é aquela em que escrevemos uma função para simular o número total de casas em um par de lançamentos. Primeiro, vamos planejar nosso código. Criaremos uma array contendo os números de 1 a 6, faremos dois sorteios aleatórios com reposição da array e somaremos os dois números sorteados.
die = np.arange(1, 7)
sum(np.random.choice(die, 2))
| Out[6]: | 7 |
Podemos usar o array die e a expressão acima para definir uma função que simula um movimento no Monopoly.
def one_simulated_move():
return sum(np.random.choice(die, 2))
Agora podemos criar uma matriz de 10.000 movimentos simulados de Monopólio, começando com uma matriz de coleção vazia e aumentando-a a cada novo movimento simulado.
num_repetitions = 10000
moves = make_array()
for i in np.arange(num_repetitions):
new_move = one_simulated_move()
moves = np.append(moves, new_move)
Aqui está um histograma dos resultados.
results = Table().with_columns(
'Repetition', np.arange(1, num_repetitions + 1),
'Sum of Two Rolls', moves
)
results.hist('Sum of Two Rolls', bins = np.arange(1.5, 12.6, 1))

Sete é o valor mais comum, com as frequências caindo simetricamente em ambos os lados.
| ← Capítulo 9.2 – Iteração | Capítulo 9.4 – Problema Monty Hall → |
