Aula 9 – Tópicos especiais para programação: geração de números pseudo-aleatórios, simulação numérica e bootstrap

Autor

Prof. Marcelo Ribeiro

Objetivo da Aula

Compreender e aplicar conceitos fundamentais de geração de números pseudo-aleatórios, simulação numérica e bootstrap no R, utilizando exemplos práticos e alguns pacotes úteis para apoio computacional e visualização dos resultados.

Comentário do professor

Nesta aula, avançaremos para um conjunto de técnicas computacionais muito importantes em Estatística, Ciência de Dados e simulação. Em vez de depender apenas de fórmulas fechadas, passaremos a usar o computador como ferramenta de experimentação probabilística.

1. Introdução

Em muitas situações de interesse estatístico, a solução analítica exata pode ser difícil, trabalhosa ou mesmo inviável. Nesses casos, técnicas computacionais tornam-se extremamente úteis. Entre elas, destacam-se:

  • a geração de números pseudo-aleatórios;
  • a simulação numérica;
  • o bootstrap.

Essas técnicas permitem:

  • reproduzir artificialmente fenômenos aleatórios;
  • estudar o comportamento de estimadores;
  • aproximar distribuições amostrais;
  • construir intervalos de confiança;
  • avaliar variabilidade e incerteza.
Comentário do professor

Uma ideia central desta aula é perceber que o computador pode ser usado não apenas para executar fórmulas, mas também para criar experimentos estatísticos controlados.

2. Pacotes utilizados

library(dplyr)
Warning: package 'dplyr' was built under R version 4.4.3

Attaching package: 'dplyr'
The following objects are masked from 'package:stats':

    filter, lag
The following objects are masked from 'package:base':

    intersect, setdiff, setequal, union
library(ggplot2)
Warning: package 'ggplot2' was built under R version 4.4.3
library(plotly)
Warning: package 'plotly' was built under R version 4.4.3

Attaching package: 'plotly'
The following object is masked from 'package:ggplot2':

    last_plot
The following object is masked from 'package:stats':

    filter
The following object is masked from 'package:graphics':

    layout
library(boot)
Comentário do professor

Nesta aula: - dplyr será usado para organizar resultados; - ggplot2 será usado para visualizações estáticas; - plotly será usado em algumas visualizações interativas; - boot será usado em exemplos de bootstrap.

3. Geração de números pseudo-aleatórios

Em R, a geração de valores aleatórios é feita por algoritmos determinísticos. Por isso, os valores gerados são chamados de pseudo-aleatórios.

3.1 Números pseudo-aleatórios Uniformes

A função runif() gera valores da distribuição Uniforme contínua.

Execute este código
runif(10)
 [1] 0.16327051 0.06582959 0.57973394 0.84133648 0.28939956 0.31522964
 [7] 0.04425745 0.52880415 0.73206046 0.26893039
Comentário do professor

A função runif(n, min, max) gera n números pseudo-aleatórios no intervalo entre min e max. - n: quantidade de valores; - min: limite inferior; - max: limite superior.

Quando min e max não são informados, o intervalo padrão é de 0 a 1.

Exemplo com outro intervalo

Execute este código
runif(10, min = 5, max = 15)
 [1]  9.577506 10.378243  5.366435  6.857255  5.615070  6.017398 14.652211
 [8]  8.849433  6.198287  5.539692

3.2 Números pseudo-aleatórios Normais

A função rnorm() gera valores pseudo-aleatórios da distribuição Normal.

Execute este código
rnorm(10, mean = 0, sd = 1)
 [1] -1.1785571  0.7856005 -0.4684197 -0.2099405  0.6126256 -0.5061299
 [7] -0.1612499  0.2535374  0.7467915  0.5357930
Comentário do professor

A função rnorm(n, mean, sd) gera n valores de uma Normal com média mean e desvio-padrão sd.

3.3 Números pseudo-aleatórios Binomiais

A função rbinom() gera valores da distribuição Binomial.

Execute este código
rbinom(10, size = 5, prob = 0.4)
 [1] 1 2 3 2 2 4 0 2 4 1
Comentário do professor

A função rbinom(n, size, prob) gera n observações da distribuição Binomial. - size: número de ensaios em cada observação; - prob: probabilidade de sucesso.

3.4 Controle de reprodutibilidade com set.seed()

Em simulação, é muito importante conseguir reproduzir os mesmos resultados.

Execute este código
set.seed(123)
runif(5)
[1] 0.2875775 0.7883051 0.4089769 0.8830174 0.9404673

Agora repita:

Execute este código
set.seed(123)
runif(5)
[1] 0.2875775 0.7883051 0.4089769 0.8830174 0.9404673
Comentário do professor

A função set.seed() fixa o estado inicial do gerador pseudo-aleatório. Assim, sempre que o mesmo código for executado com a mesma semente, os mesmos valores serão produzidos.

Ilustração 3.1 – Lógica da reprodutibilidade

flowchart LR
A["set.seed()"] --> B["Gerador pseudo-aleatório"]
B --> C["Sequência reproduzível de valores"]

4. Visualizando amostras geradas aleatoriamente

Vamos gerar uma amostra Normal com 500 observações e representá-la graficamente.

set.seed(123)

amostra_normal <- tibble(
  x = rnorm(500, mean = 10, sd = 2)
)

4.1 Histograma

Execute este código
ggplot(amostra_normal, aes(x = x)) +
  geom_histogram(bins = 20, fill = "steelblue", color = "white") +
  labs(
    title = "Histograma de uma amostra Normal simulada",
    x = "Valor",
    y = "Frequência"
  ) +
  theme_minimal()

4.2 Boxplot

Execute este código
ggplot(amostra_normal, aes(x = "", y = x)) +
  geom_boxplot(fill = "gray75", color = "black") +
  labs(
    title = "Boxplot de uma amostra Normal simulada",
    x = "",
    y = "Valor"
  ) +
  theme_minimal()

4.3 Visualização interativa com plotly

Execute este código
hist_plot <- ggplot(amostra_normal, aes(x = x)) +
  geom_histogram(bins = 20, fill = "steelblue", color = "white") +
  labs(
    title = "Histograma interativo",
    x = "Valor",
    y = "Frequência"
  ) +
  theme_minimal()

ggplotly(hist_plot)
Comentário do professor

O uso de visualizações, inclusive interativas, ajuda a perceber como a amostra simulada reflete as características da distribuição geradora.

5. Simulação numérica

A simulação numérica consiste em repetir, muitas vezes, um experimento probabilístico artificial, registrando os resultados.

5.1 Exemplo clássico: lançamento de moeda

Vamos simular 20 lançamentos de uma moeda equilibrada.

Execute este código
set.seed(321)

moeda <- sample(c("Cara", "Coroa"), size = 20, replace = TRUE)

moeda
 [1] "Coroa" "Coroa" "Cara"  "Cara"  "Cara"  "Coroa" "Coroa" "Coroa" "Coroa"
[10] "Coroa" "Cara"  "Coroa" "Cara"  "Cara"  "Cara"  "Cara"  "Coroa" "Coroa"
[19] "Cara"  "Coroa"
Comentário do professor

A função sample(x, size, replace) sorteia valores do conjunto x. - size: tamanho da amostra; - replace = TRUE: permite repetição dos elementos sorteados.

5.2 Frequência relativa de caras

Execute este código
mean(moeda == "Cara")
[1] 0.45
Comentário do professor

Como a expressão moeda == "Cara" devolve um vetor lógico (TRUE/FALSE), sua média corresponde à proporção de lançamentos com resultado “Cara”.

5.3 Repetindo o experimento muitas vezes

Agora vamos simular 1000 experimentos, cada um com 20 lançamentos, e calcular a proporção de caras em cada experimento.

Execute este código
set.seed(321)

proporcoes <- replicate(
  1000,
  mean(sample(c("Cara", "Coroa"), size = 20, replace = TRUE) == "Cara")
)

head(proporcoes)
[1] 0.45 0.35 0.65 0.55 0.50 0.55
Comentário do professor

A função replicate(n, expr) repete uma expressão n vezes e armazena os resultados.

5.4 Distribuição das proporções simuladas

Execute este código
proporcoes_df <- tibble(proporcao = proporcoes)

ggplot(proporcoes_df, aes(x = proporcao)) +
  geom_histogram(bins = 15, fill = "gray60", color = "black") +
  labs(
    title = "Distribuição da proporção de caras em 1000 simulações",
    x = "Proporção de caras",
    y = "Frequência"
  ) +
  theme_minimal()

Comentário do professor

Esse gráfico aproxima a distribuição amostral da proporção de caras em amostras de tamanho 20.

Ilustração 5.1 – Ideia de simulação numérica

flowchart LR
A["Definir mecanismo aleatório"] --> B["Repetir experimento muitas vezes"]
B --> C["Registrar resultados"]
C --> D["Estudar distribuição empírica"]

6. Simulação do comportamento da média amostral

Um uso importante da simulação é estudar o comportamento de estimadores, como a média.

6.1 Simulando médias amostrais

Vamos gerar 1000 amostras de tamanho 30 de uma Normal com média 50 e desvio-padrão 10, e calcular a média de cada amostra.

Execute este código
set.seed(456)

medias <- replicate(
  1000,
  mean(rnorm(30, mean = 50, sd = 10))
)

medias_df <- tibble(media = medias)

head(medias_df)

6.2 Histograma das médias amostrais

Execute este código
ggplot(medias_df, aes(x = media)) +
  geom_histogram(bins = 20, fill = "darkred", color = "white") +
  labs(
    title = "Distribuição das médias amostrais",
    x = "Média amostral",
    y = "Frequência"
  ) +
  theme_minimal()

Comentário do professor

Esse exemplo ajuda a compreender uma ideia central da inferência estatística: a média amostral é uma variável aleatória, e portanto possui sua própria distribuição.

6.3 Sumarização das médias simuladas

Execute este código
tibble(
  media_das_medias = mean(medias),
  desvio_padrao_das_medias = sd(medias),
  minimo = min(medias),
  maximo = max(medias)
)

7. Bootstrap

O bootstrap é uma técnica de reamostragem com reposição usada para aproximar a distribuição amostral de um estimador.

7.1 Ideia central do bootstrap

Suponha que temos uma amostra observada:

amostra_boot <- c(7.8, 6.2, 8.9, 5.7, 8.4, 6.8, 9.1, 5.9, 9.3, 6.4)

O bootstrap consiste em:

  1. sortear, com reposição, uma nova amostra do mesmo tamanho;
  2. calcular o estimador de interesse;
  3. repetir esse processo muitas vezes;
  4. usar os resultados para estudar a variabilidade do estimador.

Ilustração 7.1 – Ideia do bootstrap

flowchart LR
A["Amostra original"] --> B["Reamostragem com reposição"]
B --> C["Cálculo do estimador"]
C --> D["Repetição muitas vezes"]
D --> E["Distribuição bootstrap do estimador"]

7.2 Reamostrando manualmente

Execute este código
set.seed(789)

sample(amostra_boot, size = length(amostra_boot), replace = TRUE)
 [1] 5.7 6.4 6.4 8.9 8.4 5.7 8.9 6.8 5.7 7.8
Comentário do professor

No bootstrap, a amostra reamostrada tem o mesmo tamanho da amostra original, mas é construída com reposição, de modo que alguns valores podem se repetir e outros podem não aparecer.

7.3 Bootstrap manual da média

Vamos repetir o procedimento 2000 vezes para a média.

Execute este código
set.seed(789)

medias_boot <- replicate(
  2000,
  mean(sample(amostra_boot, size = length(amostra_boot), replace = TRUE))
)

boot_df <- tibble(media_boot = medias_boot)

head(boot_df)

7.4 Visualizando a distribuição bootstrap da média

Execute este código
ggplot(boot_df, aes(x = media_boot)) +
  geom_histogram(bins = 20, fill = "darkgreen", color = "white") +
  labs(
    title = "Distribuição bootstrap da média",
    x = "Média bootstrap",
    y = "Frequência"
  ) +
  theme_minimal()

7.5 Estimando erro-padrão bootstrap

Execute este código
sd(medias_boot)
[1] 0.428897
Comentário do professor

O desvio-padrão das estimativas bootstrap pode ser interpretado como uma aproximação do erro-padrão do estimador.

7.6 Intervalo bootstrap percentílico

Execute este código
quantile(medias_boot, probs = c(0.025, 0.975))
   2.5%   97.5% 
6.61975 8.28000 
Comentário do professor

Os percentis 2,5% e 97,5% fornecem um intervalo bootstrap percentílico de 95% para a média.

8. Bootstrap com o pacote boot

O pacote boot oferece uma implementação mais estruturada da técnica.

8.1 Definindo a estatística de interesse

Vamos construir uma função que calcule a média em uma reamostra.

media_boot_fun <- function(dados, indices) {
  amostra <- dados[indices]
  mean(amostra)
}
Comentário do professor

Na função usada pelo boot(): - dados: vetor original; - indices: índices sorteados na reamostragem.

8.2 Aplicando boot()

Execute este código
set.seed(789)

resultado_boot <- boot(
  data = amostra_boot,
  statistic = media_boot_fun,
  R = 2000
)

resultado_boot

ORDINARY NONPARAMETRIC BOOTSTRAP


Call:
boot(data = amostra_boot, statistic = media_boot_fun, R = 2000)


Bootstrap Statistics :
    original   bias    std. error
t1*     7.45 0.016855   0.4183121
Comentário do professor

A função boot(data, statistic, R) executa o bootstrap: - data: dados originais; - statistic: função que calcula a estatística; - R: número de reamostragens.

8.3 Intervalo com boot.ci()

Execute este código
boot.ci(resultado_boot, type = "perc")
BOOTSTRAP CONFIDENCE INTERVAL CALCULATIONS
Based on 2000 bootstrap replicates

CALL : 
boot.ci(boot.out = resultado_boot, type = "perc")

Intervals : 
Level     Percentile     
95%   ( 6.65,  8.27 )  
Calculations and Intervals on Original Scale
Comentário do professor

A função boot.ci() calcula intervalos de confiança bootstrap. - type = "perc" solicita o intervalo percentílico.

8.4 Visualizando os resultados do boot

Execute este código
resultado_boot_df <- tibble(
  media_boot = resultado_boot$t[, 1]
)

ggplot(resultado_boot_df, aes(x = media_boot)) +
  geom_histogram(bins = 20, fill = "purple", color = "white") +
  labs(
    title = "Distribuição bootstrap da média com o pacote boot",
    x = "Média bootstrap",
    y = "Frequência"
  ) +
  theme_minimal()

9. Exemplo de bootstrap para a mediana

O bootstrap é especialmente útil para estatísticas cuja teoria analítica é mais complicada, como a mediana.

9.1 Bootstrap manual da mediana

Execute este código
set.seed(321)

medianas_boot <- replicate(
  2000,
  median(sample(amostra_boot, size = length(amostra_boot), replace = TRUE))
)

medianas_df <- tibble(mediana_boot = medianas_boot)

ggplot(medianas_df, aes(x = mediana_boot)) +
  geom_histogram(bins = 20, fill = "orange", color = "white") +
  labs(
    title = "Distribuição bootstrap da mediana",
    x = "Mediana bootstrap",
    y = "Frequência"
  ) +
  theme_minimal()

9.2 Intervalo percentílico para a mediana

Execute este código
quantile(medianas_boot, probs = c(0.025, 0.975))
 2.5% 97.5% 
 6.15  9.00 
Comentário do professor

Esse é um bom exemplo de situação em que o bootstrap é particularmente útil: quando o estimador de interesse não tem uma expressão simples para erro-padrão e intervalo de confiança.

10. Exemplo integrado com dados da aula

Agora vamos aplicar bootstrap à média de um conjunto de notas em contexto compatível com a aula.

10.1 Reamostrando a média das notas

Execute este código
notas <- c(7.8, 6.2, 8.9, 5.7, 8.4, 6.8, 9.1, 5.9, 9.3, 6.4,
           8.0, 5.8, 9.5, 6.9, 9.0, 7.1, 8.7, 6.5)

set.seed(654)

medias_nota <- replicate(
  2000,
  mean(sample(notas, size = length(notas), replace = TRUE))
)

medias_nota_df <- tibble(media_boot = medias_nota)

head(medias_nota_df)

10.2 Histograma das médias bootstrap

Execute este código
ggplot(medias_nota_df, aes(x = media_boot)) +
  geom_histogram(bins = 20, fill = "navy", color = "white") +
  labs(
    title = "Distribuição bootstrap da média das notas",
    x = "Média bootstrap",
    y = "Frequência"
  ) +
  theme_minimal()

10.3 Intervalo bootstrap para a média das notas

Execute este código
quantile(medias_nota, probs = c(0.025, 0.975))
    2.5%    97.5% 
6.933194 8.161389 

10.4 Visualização interativa com plotly

Execute este código
graf_boot <- ggplot(medias_nota_df, aes(x = media_boot)) +
  geom_histogram(bins = 20, fill = "navy", color = "white") +
  labs(
    title = "Distribuição bootstrap interativa da média das notas",
    x = "Média bootstrap",
    y = "Frequência"
  ) +
  theme_minimal()

ggplotly(graf_boot)

11. Exemplos de uso de pacotes do R

Nesta aula, já utilizamos alguns pacotes importantes. Vamos resumir seu papel:

11.1 dplyr

Usado para organizar resultados.

Execute este código
medias_nota_df %>%
  summarise(
    media = mean(media_boot),
    desvio_padrao = sd(media_boot),
    q025 = quantile(media_boot, 0.025),
    q975 = quantile(media_boot, 0.975)
  )

11.2 ggplot2

Usado para construir gráficos de distribuições simuladas e bootstrap.

11.3 plotly

Usado para gerar visualizações interativas, que ajudam a explorar a distribuição dos resultados.

11.4 boot

Usado para implementar o bootstrap de forma sistemática.

Comentário do professor

Em R, a combinação de pacotes permite construir fluxos de análise mais claros, reprodutíveis e didáticos. O importante não é apenas conhecer comandos isolados, mas compreender a função de cada ferramenta dentro do processo analítico.

12. Erros comuns e boas práticas

Erros comuns
  • esquecer de usar set.seed() quando a reprodutibilidade é necessária;
  • interpretar pseudo-aleatoriedade como aleatoriedade “verdadeira”;
  • usar poucas repetições em simulações, produzindo resultados instáveis;
  • aplicar bootstrap sem compreender que a reamostragem é feita a partir da própria amostra observada;
  • confundir distribuição dos dados com distribuição do estimador.
Boas práticas
  • documente a semente usada quando necessário;
  • use número suficientemente grande de repetições em simulações e bootstrap;
  • interprete gráficos e resumos em conjunto;
  • compare o valor original do estimador com o comportamento de sua distribuição obtida por simulação ou bootstrap.

13. Exercícios propostos

Exercício 1

Gere:

  • 20 valores pseudo-aleatórios Uniformes no intervalo ([0,1]);
  • 20 valores pseudo-aleatórios Normais com média 10 e desvio-padrão 3;
  • 20 valores Binomiais com size = 8 e prob = 0.4.

Exercício 2

Mostre, com um exemplo, como set.seed() garante a reprodutibilidade de uma sequência pseudo-aleatória.

Exercício 3

Simule 1000 experimentos de lançamento de uma moeda equilibrada, com 30 lançamentos em cada experimento, e construa o histograma da proporção de caras.

Exercício 4

Simule 1000 médias amostrais de amostras de tamanho 25 extraídas de uma Normal com média 100 e desvio-padrão 15. Em seguida, represente graficamente a distribuição dessas médias.

Exercício 5

Considere a amostra:

c(4.8, 5.1, 5.4, 6.0, 6.2, 6.5, 6.8, 7.0, 7.3, 7.5)

Aplique bootstrap manual para estimar: - a distribuição da média; - o erro-padrão bootstrap da média; - um intervalo percentílico de 95%.

Exercício 6

Repita o exercício anterior para a mediana.

Exercício 7

Use o pacote boot para obter a distribuição bootstrap da média da amostra do Exercício 5.

Exercício 8

Aplique bootstrap ao vetor de notas utilizado na aula para obter: - a distribuição bootstrap da média; - um intervalo percentílico de 95%.

Exercício 9

Construa uma visualização interativa, com plotly, para a distribuição bootstrap da média das notas.

Exercício 10

Explique, com suas palavras, a diferença entre: - distribuição dos dados; - distribuição amostral de um estimador; - distribuição bootstrap de um estimador.

Comentário do professor

Os exercícios desta aula foram formulados para consolidar o uso da simulação como ferramenta estatística e computacional, integrando geração aleatória, repetição de experimentos e reamostragem.

Tarefa do aluno

Refaça os exemplos da aula e procure comparar o comportamento do estimador original com o comportamento de sua distribuição obtida por simulação ou bootstrap.