O objetivo desta sessão é mostrar o uso de funções do R em problemas de probabilidade. Exercícios que podem (e devem!) ser resolvidos analiticamente, serão utilizados para ilustrar o uso do programa e alguns de seus recursos para análises numéricas.
Os problemas desta sessão foram retirados do livro de Bussab e Morettin (2003).
Dada a função
\[ \ f(x) = \left\{ \begin{array}{ll} 2 e^{-2x} & \mbox{ , se $ \; x \geq 0$} \cr 0 & \mbox{ , se $ \; x < 0$} \end{array} \right. \ \]
Para ser f.d.p. a função não deve ter valores negativos e deve integrar 1 em seu domínio. Vamos começar definindo esta função como uma função no R para qual daremos o nome de f1
.
f1 <- function(x){
fx <- ifelse(x < 0, 0, 2 * exp(-2 * x))
return(fx)
}
A seguir fazemos o gráfico da função. Como a função tem valores positivos para \(x\) no intervalo de zero a infinito, temos que definir um limite em \(x\) até onde vai o gráfico da função. Vamos achar este limite tentando vários valores, conforme mostram os comandos abaixo.
par(mfrow = c(2, 2))
plot(f1)
plot(f1, from = 0, to = 5)
plot(f1, from = 0, to = 7)
plot(f1, from = 0, to = 10)
par(mfrow = c(1, 1))
Para verificar que a a integral da função é igual a 1 podemos usar a função integrate()
, que efetua integração numérica. A função recebe como argumentos o objeto com a função a ser integrada e os limites de integração. Neste exemplo o objeto é f1
definido acima, e o domínio da função é \([0, \infty]\). A saída da função mostra o valor da integral acima, e o erro máximo da aproximação numérica.
integrate(f1, lower = 0, upper = Inf)
## 1 with absolute error < 5e-07
Para fazer cálculos pedidos nos itens (b) e (c) lembramos que a probabilidade é dada pela área sob a curva da função no intervalo pedido. Desta forma as soluções seriam dadas pelas expressões
\[ \begin{eqnarray*} p_b & = & P(X > 1) = \int_1^\infty f(x) dx = \int_1^\infty 2\,e^{-2x} dx \\ p_c & = & P(0,2 < X < 0,8) = \int_{0,2}^{0,8} f(x) dx = \int_{0.2}^{0.8} 2\,e^{-2x} dx \, \end{eqnarray*} \]
cuja representação gráfica é mostrada na abaixo.
Os comandos a seguir mostram como fazer o gráfico dessas funções. O comando plot()
desenha o gráfico principal, e para destacar as áreas que correspondem às probabilidades pedidas vamos usar a função polygon()
. Esta função adiciona a um gráfico um polígono que é definido pelas coordenadas de seus vértices. Para sombrear a área usa-se o argumento density
. Finalmente, para escrever um texto no gráfico usamos a função text()
com as coordenadas de posição do texto.
plot(f1, from = 0, to = 5)
polygon(x = c(1, seq(1, 5, length.out = 20)),
y = c(0, f1(seq(1, 5,length.out = 20))),
density = 10)
polygon(x = c(0.2, seq(0.2, 0.8, length.out = 20), 0.8),
y = c(0, f1(seq(0.2, 0.8, length.out = 20)), 0),
col = "gray")
text(x = c(1.2, 0.5), y = c(0.1, 0.2),
c(expression(p[b], p[c])))
E para obter as probabilidades pedidas usamos integrate()
.
integrate(f1, lower = 1, upper = Inf)
## 0.1353353 with absolute error < 2.1e-05
integrate(f1, lower = 0.2, upper = 0.8)
## 0.4684235 with absolute error < 5.2e-15
O R inclui funcionalidade para operações com distribuições de probabilidades. Para cada distribuição há 4 operações básicas indicadas pelas letras:
d
calcula a densidade de probabilidade \(f(x)\) no pontop
calcula a função de probabilidade acumulada \(F(x)\) no pontoq
calcula o quantil correspondente a uma dada probabilidader
retira uma amostra aleatória da distribuiçãoPara usar os funções deve-se combinar uma das letras acima com uma abreviatura do nome da distribuição. Por exemplo, para calcular probabilidades usamos: pnorm()
para normal, pexp()
para exponencial, pbinom()
para binomial, ppois()
para Poisson e assim por diante.
Vamos ver com mais detalhes algumas distribuições de probabilidades.
A funcionalidade para distribuição normal é implementada por argumentos que combinam as letras acima com o termo norm
. Vamos ver alguns exemplos com a distribuição normal padrão. Por default
as funções assumem a distribuição normal padrão \(N(\mu=0, \sigma^2=1)\).
dnorm(-1)
## [1] 0.2419707
pnorm(-1)
## [1] 0.1586553
qnorm(0.975)
## [1] 1.959964
rnorm(10)
## [1] -0.50219235 0.13153117 -0.07891709 0.88678481 0.11697127
## [6] 0.31863009 -0.58179068 0.71453271 -0.82525943 -0.35986213
O primeiro valor acima, de dnorm(-1)
, corresponde ao valor da densidade da normal
\[ f(x) = \frac{1}{\sigma\sqrt{2 \pi}}\exp \left[ -\frac{1}{2} \left( \frac{x - \mu}{\sigma} \right)^2 \right] \]
com parâmetros \((\mu=0, \sigma^2=1)\) no ponto \(x = -1\). Portanto, o mesmo valor seria obtido substituindo \(x\) por \(-1\) na expressão da normal:
mu <- 0
sigma <- 1
x <- -1
(1/(sigma * sqrt(2*pi))) * exp((-1/2) * ((x - mu)/sigma)^2)
## [1] 0.2419707
A função pnorm(-1)
calcula a probabilidade \(P(X \leq -1)\). O comando qnorm(0.975)
calcula o valor de \(a\) tal que \(P(X \leq a) = 0.975\). Finalmente, o comando rnorm(10)
gera uma amostra aleatória de 10 elementos da normal padrão. Note que os valores que você obtém rodando este comando podem ser diferentes dos mostrados acima.
As funções acima possuem argumentos adicionais, para os quais valores padrão (default) foram assumidos, e que podem ser modificados. Usamos args()
para ver os argumentos de uma função e help()
para visualizar a documentação detalhada:
args(rnorm)
## function (n, mean = 0, sd = 1)
## NULL
As funções relacionadas à distribuição normal possuem os argumentos mean
e sd
para definir média e desvio padrão da distribuição que podem ser modificados como nos exemplos a seguir. Note nestes exemplos que os argumentos podem ser passados de diferentes formas.
qnorm(0.975, mean = 100, sd = 8)
## [1] 115.6797
qnorm(0.975, m = 100, s = 8)
## [1] 115.6797
qnorm(0.975, 100, 8)
## [1] 115.6797
Observação: na segunda linha de comando acima, foi utilizado um recurso do R chamado partial matching. Isso significa que nomes de argumentos de funções podem ser especificados pelo seu nome parcial, ou seja, com apenas o início do nome, desde que não haja ambiguação com outros argumentos.
Para informações mais detalhadas pode-se usar help()
. O comando
help(rnorm)
irá exibir em uma janela a documentação da função que pode também ser chamada com ?rnorm
. Note que ao final da documentação são apresentados exemplos que podem ser rodados pelo usuário e que auxiliam na compreensão da funcionalidade. Note também que as 4 funções relacionadas à distribuição normal são documentadas conjuntamente, portanto help(rnorm)
, help(qnorm)
, help(dnorm)
e help(pnorm)
irão exibir a mesma documentação.
Cálculos de probabilidades usuais, para os quais utilizávamos tabelas estatísticas podem ser facilmente obtidos como no exemplo a seguir.
Seja \(X\) uma VA com distribuição \(N(100, 100)\). Calcular as probabilidades:
Calcule estas probabilidades de forma usual, usando a tabela da normal. Depois compare com os resultados fornecidos pelo R. Os comandos do para obter as probabilidades pedidas são:
## P[X < 95]
pnorm(95, 100, 10)
## [1] 0.3085375
## P[90 < X < 110]
pnorm(110, 100, 10) - pnorm(90, 100, 10)
## [1] 0.6826895
## P[X > 95] = 1 - P[X < 95]
1 - pnorm(95, 100, 10)
## [1] 0.6914625
pnorm(95, 100, 10, lower.tail = FALSE) # melhor
## [1] 0.6914625
Note que a última probabilidade foi calculada de duas formas diferentes, a segunda usando o argumento lower.tail
que implementa um algorítmo de cálculo de probabilidades mais estável numericamente, e essa forma é preferida no lugar de usar o complementar.
A seguir vamos ver comandos para fazer gráficos de distribuições de probabilidade. Vamos fazer gráficos de funções de densidade e de probabilidade acumulada. Estude cuidadosamente os comandos abaixo e verifique os gráficos por eles produzidos.
A figura abaixo mostra gráficos da densidade (esquerda) e probabilidade acumulada (direita) da normal padrão, produzidos com os comandos a seguir. Para fazer o gráfico consideramos valores de \(X\) entre -3 e 3 que correspondem a +/- três desvios padrões da média, faixa que concentra 99,73% da massa de probabilidade da distribuição normal.
par(mfrow = c(1, 2))
plot(dnorm, from = -3, to = 3)
plot(pnorm, from = -3, to = 3)
par(mfrow = c(1, 1))
VEJA a página de ajuda da função
plot.function()
para entender os argumentos e demais funcionalidades desta função gráfica para plotar gráficos de funções
A seguinte figura mostra gráficos da densidade (esquerda) e probabilidade acumulada (direita) da \(N(100, 64)\). Para fazer estes gráficos tomamos uma sequência de valores de \(X\) entre 70 e 130 e para cada um deles calculamos o valor das funções \(f(x)\) e \(F(x)\). Depois unimos os pontos \((x,f(x))\) em um gráfico e \((x,F(x))\) no outro.
par(mfrow = c(1, 2))
x <- seq(70, 130, length.out = 100)
fx <- dnorm(x, 100, 8)
plot(x, fx, type = "l")
Fx <- pnorm(x, 100, 8)
plot(x, Fx, type = "l")
par(mfrow = c(1, 1))
Note que, alternativamente, os mesmos gráficos poderiam ser produzidos com os comandos a seguir, onde fazemos usa da função plot.function()
.
par(mfrow = c(1, 2))
plot(function(x) dnorm(x, 100, 8), from = 70, to = 130)
plot(function(x) pnorm(x, 100, 8), from = 70, to = 130)
par(mfrow = c(1, 1))
Comandos usuais do R podem ser usados para modificar a aparência dos gráficos. Por exemplo, podemos incluir títulos e mudar texto dos eixos conforme mostrado abaixo.
plot(dnorm, from = -3, to = 3,
xlab = "Valores de X",
ylab = "Densidade de probabilidade")
title("Distribuicão Normal\nX ~ N(100, 64)")
Os demais comandos abaixo mostram como colocar diferentes densidades em um mesmo gráfico, usando o argumento add = TRUE
.
plot(function(x) dnorm(x, 100, 8), 60, 140, ylab = 'f(x)')
plot(function(x) dnorm(x, 90, 8), 60, 140, add = TRUE, col = 2)
plot(function(x) dnorm(x, 100, 15), 60, 140, add = TRUE, col = 3)
legend(120, 0.05, fill = 1:3,
legend = c("N(100,64)", "N(90,64)", "N(100,225)"))
Cálculos para a distribuição binomial são implementados combinando as letras básicas vistas acima com o termo binom
. Vamos primeiro investigar argumentos e documentação com args()
e help()
.
args(dbinom)
## function (x, size, prob, log = FALSE)
## NULL
help(dbinom)
Seja \(X\) uma VA com distribuição Binomial, com \(n=10\) e \(p=0.35\). Vamos ver os comandos do R para:
Note que sendo uma distribuição discreta de probabilidades os gráficos são diferentes dos obtidos para distribuição normal e os cálculos de probabilidades devem considerar as probabilidades nos pontos. Os gráficos das funções de densidade e probabilidade são mostrados abaixo.
par(mfrow = c(1, 2))
x <- 0:10
fx <- dbinom(x, size = 10, prob = 0.35)
plot(x, fx, type = "h")
Fx <- pbinom(x, size = 10, prob = 0.35)
plot(x, Fx, type = "s")
par(mfrow = c(1, 1))
As probabilidades pedidas são obtidas com os comandos a seguir.
## P[X = 7]
dbinom(7, size = 10, prob = 0.35)
## [1] 0.02120302
## P[X <= 7]
pbinom(7, size = 10, prob = 0.35)
## [1] 0.9951787
# OU
sum(dbinom(0:7, size = 10, prob = 0.35))
## [1] 0.9951787
## P[X > 7]
1 - pbinom(7, size = 10, prob = 0.35)
## [1] 0.004821265
pbinom(7, size = 10, prob = 0.35, lower.tail = FALSE) # melhor
## [1] 0.004821265
## P[3 < X <= 6]
pbinom(6, 10, 0.35) - pbinom(3, 10, 0.35)
## [1] 0.4601487
# OU
sum(dbinom(4:6, 10, 0.35))
## [1] 0.4601487
Definição: Seja um experimento realizado nas seguintes condições: i. As ocorrências são independentes ii. As ocorrências são aleatórias iii. A variável aleatória \(X\) é o número de ocorrências de um evento ao longo de algum intervalo} (de tempo ou espaço)
Denominamos esse experimento de processo de Poisson. Vamos associar a V.A. \(X\) o número de ocorrências em um intervalo. Portanto \(X\) poderá assumir os valores \(0, 1, \ldots,\) (sem limite superior).
A distribuição de Poisson é utilizada para descrever a probabilidade do número de ocorrências em um intervalo contínuo (de tempo ou espaço). No caso da distribuição binomial, a variável de interesse era o número de sucessos em um intervalo discreto (\(n\) ensaios de Bernoulli). A unidade de medida (tempo ou espaço) é uma variável contínua, mas a variável aleatória, o número de ocorrências}, é discreta.
Uma V.A. \(X\) segue o modelo de Poisson se surge a partir de um processo de Poisson, e sua função de probabilidade} for dada por
\[ P[X = x] = \frac{e^{-\mu} \mu^x}{x!}, \quad \quad x = 0, 1, \ldots \]
onde
\[ \mu = \lambda \cdot t \]
O parâmetro \(\mu\) indica a taxa de ocorrência (\(\lambda\)) por unidade de medida (\(t\)), ou seja,
\[ \lambda = \text{taxa de ocorrência} \quad \text{e} \quad t = \text{intervalo de tempo ou espaço} \]
Alguns exemplos de gráficos da distribuição de Poisson com diferentes valores do parâmetro \(\mu\).
par(mfrow=c(2,2))
plot(0:30, dpois(x = 0:30, lambda = 1), type = "h",
xlab = "X", ylab = "P[X = x]", main = expression(mu == 1),
ylim = c(0,.4))
plot(0:30, dpois(x = 0:30, lambda = 5), type = "h",
xlab = "X", ylab = "P[X = x]", main = expression(mu == 5),
ylim = c(0,.4))
plot(0:30, dpois(x = 0:30, lambda = 10), type = "h",
xlab = "X", ylab = "P[X = x]", main = expression(mu == 10),
ylim = c(0,.4))
plot(0:30, dpois(x = 0:30, lambda = 15), type = "h",
xlab = "X", ylab = "P[X = x]", main = expression(mu == 15),
ylim = c(0,.4))
## a) E(X) = mu = lambda . t
lambda <- 8/60 # 8 chamadas/60 minutos
t <- 15 # 15 minutos
(mu <- lambda * t)
## [1] 2
## b) P[x = 0]
ppois(0, mu)
## [1] 0.1353353
dpois(0, mu)
## [1] 0.1353353
## c) P[X >= 2] = 1 - P[X < 2]
1 - ppois(1, mu)
## [1] 0.5939942
ppois(1, mu, lower.tail = FALSE)
## [1] 0.5939942
## d) P[X = 2]
t <- 20
(mu <- lambda * t)
## [1] 2.666667
dpois(2, mu)
## [1] 0.2470523
## lambda = taxa de ocorrência por página
lambda <- 150/200
## intervalo de interesse
t <- 2
## Parâmetro mu = lambda . t
(mu <- lambda * t)
## [1] 1.5
## a) P[X = 0]
dpois(0, mu)
## [1] 0.2231302
## b) P[X = 3]
dpois(3, mu)
## [1] 0.1255107
## c) P[X >= 1] = 1 - P[X < 1]
1 - ppois(0, mu)
## [1] 0.7768698
ppois(0, mu, lower.tail = FALSE)
## [1] 0.7768698
Para a distribuição uniforme contínua usa-se as funções *unif()
onde *
deve ser \(p\), \(q\), \(d\) ou \(r\) como mencionado anteriormente. Nos comandos a seguir inspecionamos os argumentos, sorteamos 5 valores da \(U(0,1)\) e calculamos a probabilidade acumulada até 0,75.
r args(runif)
## function (n, min = 0, max = 1) ## NULL
r runif(5)
## [1] 0.5358112 0.7108038 0.5383487 0.7489722 0.4201015
r punif(0.75)
## [1] 0.75
Portanto, o default é uma distribuição uniforme no intervalo \([0,1]\) e os argumentos opcionais são min
e max
. Por exemplo, para simular 5 valores de \(X \sim U(5, 20)\) usamos:
runif(5, min = 5, max = 20)
## [1] 7.571303 16.554524 18.229304 13.236451 9.165856
Não há entre as funções básicas do R uma função específica para a distribuição uniforme discreta com opções de prefixos \(r,d,p\) e \(d\), provavelmente devido a sua simplicidade, embora algumas outras funções possam ser usadas. Por exemplo para sortear números pode-se usar sample()
, como no exemplo a seguir onde são sorteados 15 valores de uma uniforma discreta com valores (inteiros) entre 1 e 10 (\(X \sim U_d(1,10)\)).
sample(1:10, size = 15, replace = TRUE)
## [1] 5 10 4 10 7 9 2 7 10 2 4 9 8 9 7
sample()
A função sample()
não é restrita à distribuição uniforme discreta, podendo ser usada para sorteios, com ou sem reposição (argumento replace
, que por padrão é FALSE
, ou seja, sem reposição), com a possibilidade de associar diferentes probabilidades a cada elemento (argumento prob
, que por padrão associa probabilidades iguais para todos os elementos).
args(sample)
## function (x, size, replace = FALSE, prob = NULL)
## NULL
Vejamos alguns exemplos:
sample(0:20, size = 3)
## [1] 10 15 16
x
x <- c(23, 34, 12, 22, 17, 28, 18, 19, 20, 13, 18)
sample(x, size = 5)
## [1] 12 22 18 34 19
sample(1:6, size = 10, replace = TRUE)
## [1] 2 4 2 1 2 4 2 3 4 6
sample(1:6, size = 10, replace = TRUE, prob = 1:6)
## [1] 4 5 5 5 5 6 4 5 5 4
Este último exemplo ilustra ainda que os valores passados para o argumento prob
não precisam ser probabilidades, são apenas entendidos como pesos. A própria função trata isto internamente fazendo a ponderação adequada.
Agora que já nos familiarizamos com o uso das distribuições de probabilidade vamos ver alguns detalhes adicionais sobre seu funcionamento.
A probabilidade de um evento em uma distribuição contínua é uma área sob a curva da distribuição. Vamos reforçar esta idéia revisitando um exemplo visto na distribuição normal.
Seja \(X\) uma VA com distribuição \(N(100, 100)\). Para calcular a probabilidade \(P[X < 95]\) usamos o comando:
pnorm(95, mean = 100, sd = 10)
## [1] 0.3085375
Vamos agora “esquecer” o comando pnorm()
e ver uma outra forma de resolver usando integração numérica. Lembrando que a normal tem a função de densidade dada por
\[ f(x) = \frac{1}{\sigma\sqrt{2 \pi}}\exp \left[ -\frac{1}{2} \left( \frac{x - \mu}{\sigma} \right)^2 \right] \]
Podemos então definir uma função no R para calcular qualquer densidade em \(x\)
fn <- function(x, mu, sigma){
(1/(sigma * sqrt(2*pi))) * exp((-1/2) * ((x - mu)/sigma)^2)
}
Para obter o gráfico desta distribuição, usamos o fato que a maior parte da função está no intervalo entre a média +/- três desvios padrões, portanto entre 70 e 130. Podemos então fazer como nos comandos que se seguem. Para marcar no gráfico a área que corresponde a probabilidade pedida criamos um polígono com coordenadas ax
e ay
definindo o perímetro desta área.
x <- seq(70, 130, length.out = 200)
fx <- fn(x, mu = 100, sigma = 10)
plot(x, fx, type = "l")
ax <- c(70, 70, x[x < 95], 95, 95)
ay <- c(0, fn(70, 100, 10), fx[x < 95], fn(95, 100, 10),0)
polygon(ax, ay, density = 10)
Para calcular a área pedida sem usar a função pnorm()
podemos usar a função de integração numérica. Note que esta função, diferentemente da pnorm()
reporta ainda o erro de aproximação numérica.
integrate(fn, mu = 100, sigma = 10, lower = -Inf, upper = 95)
## 0.3085375 with absolute error < 2.1e-06
Portanto para os demais ítens do problema, \(P[90 < X < 110]\), e \(P[X > 95]\) fazemos:
integrate(fn, mu = 100, sigma = 10, lower = 90, upper = 110)
## 0.6826895 with absolute error < 7.6e-15
integrate(fn, mu = 100, sigma = 10, lower = 95, upper = +Inf)
## 0.6914625 with absolute error < 8.1e-05
e os resultados acima evidentemente coincidem com os obtidos anterioriormente usando pnorm()
,
pnorm(110, 100, 10) - pnorm(90, 100, 10)
## [1] 0.6826895
pnorm(95, 100, 10, lower.tail = FALSE)
## [1] 0.6914625
Note ainda que na prática não precisamos definir e usar a função fn()
, pois ela fornece o mesmo resultado que a função dnorm()
.
Nos exercícios abaixo iremos também usar o R como uma calculadora estatística para resolver alguns exemplos/exercícios de probabilidade tipicamente apresentados em um curso de estatística básica.
Este conteúdo está disponível por meio da Licença Creative Commons 4.0