6  Técnica da Inversão para Variáveis Contínuas

Os valores que uma variável aleatória \(X\) pode assumir são chamados de suporte da distribuição de \(X\).

Variáveis Aleatórias Contínuas são variáveis aleatórias que têm suporte em um conjunto não enumerável de valores, como intervalos na reta real, \(\mathbb{R}\), ou \((0,\infty)\), por exemplo.

Uma variável aleatória \(X\) contínua tem função de distribuição acumulada (f.d.a.) puder ser expressa como \[ P(X \leq a) = F(a) = \int_{-\infty}^{a} f(x) dx, \quad \forall a \in \mathbb{R}, \] em que \(f: \mathbb{R} \to [0, \infty)\) é uma função integrável, chamada de função densidade de probabilidade.

6.1 Função Inversa

Sabemos que \(F: \mathbb{R} \to [0,1]\) é estritamente crescente quando \(X\) é continua, e, portanto, podemos definir sua função inversa \(F^{-1}: [0,1] \to \mathbb{R}\). A seguinte figura ilustra \(F\) e sua inversa.

Mostrar código
# Carregando as bibliotecas necessárias
library(ggplot2)

# Definindo a função de distribuição acumulada F(x) - função logística
F_ac <- function(x) {
  return(1 / (1 + exp(-x)))
}

# Definindo a inversa da função de distribuição acumulada F_inv(u)
F_inv <- function(u) {
  return(-log((1 / u) - 1))
}

# Gerando valores de x e u
x <- seq(-4, 10, length.out = 400)
u <- seq(0.01, 0.99, length.out = 400)

# Definindo o valor de U para plotar as linhas
u_value <- 0.7
x_value <- F_inv(u_value)

# Criando o gráfico
ggplot(data = data.frame(x = x, F_x = F_ac(x))) +
  geom_line(aes(x = x, y = F_x), color = "black") +
  geom_hline(yintercept = u_value, linetype = "dotted", color = "red") +
  geom_vline(xintercept = x_value, linetype = "dotted", color = "red") +
  annotate("text", x = x_value - 0.4, y = -0, label = expression(F^{-1}(u)), color = "red", size = 5) +
  annotate("text", x = -5.5, y = u_value - 0.02, label = "u", color = "red", size = 5) +
  labs(title = "Representação da Função de Distribuição Acumulada e sua Inversa",
       x = "x", y = "F(x)") +
  ylim(0, 1.2) +
  theme_minimal()

Mostrar código
import numpy as np
import matplotlib.pyplot as plt
 
# Definindo a função de distribuição acumulada F(x)
def F(x):
    return 1 / (1 + np.exp(-x))  # Função logística como exemplo de F(x)

# Definindo a inversa da função de distribuição acumulada F_inv(u)
def F_inv(u):
    return -np.log((1 / u) - 1)

# Gerando valores de x e u para plotar
x = np.linspace(-4, 10, 400)
u = np.linspace(0.01, 0.99, 400)  # U entre 0 e 1 (evitando extremos para evitar erros na inversa)

# Plotando a função de distribuição acumulada F(x) com truncamento do eixo y no zero
plt.figure(figsize=(8, 6))
plt.plot(x, F(x), color="black")

# Adicionando linhas pontilhadas para representar U e F_inv(U)
u_value = 0.7  # Exemplo de valor de U
x_value = F_inv(u_value)

plt.hlines(u_value, min(x), x_value, linestyles='dotted', colors='red')
plt.vlines(x_value, 0, u_value, linestyles='dotted', colors='red')

# Etiquetas
plt.text(x_value-0.4 , -0.05, r"$F^{-1}(u)$", fontsize=12, color='red')
plt.text(-5.5, u_value - 0.02, r"$u$", fontsize=14, color='red')

# Rótulos e estilo do gráfico
plt.title(r'Representação da Função de Distribuição Acumulada e sua Inversa', fontsize=14)
plt.xlabel(r'$x$', fontsize=12)
plt.ylabel(r'$F(x)$', fontsize=12)
plt.ylim(0, 1.2)
(0.0, 1.2)
Mostrar código
plt.xlim(-4, 10)
(-4.0, 10.0)
Mostrar código
plt.grid(True)

# Exibir o gráfico
plt.show()

6.2 Método da Inversão

Uma maneira de gerar valores de uma variável aleatória contínua \(X\), é o método da inversão, que é originado da seguinte proposição:

Proposição: Seja \(U \sim \text{Unif}(0,1)\). Para qualquer variável aleatória contínua com função de distribuição acumulada \(F\), a variável: \[ X = F^{-1}(U) \] tem distribuição \(F\).

Prova: \[ \mathbb{P}(X \leq x) = \mathbb{P}(F^{-1}(U) \leq x) = \mathbb{P}(F(F^{-1}(U)) \leq F(x)) = \mathbb{P}(U \leq F(x)) = F(x). \]

Assim, o método da inversão consiste em:

  1. Gerar \(U \sim \text{Unif}(0,1)\).

  2. Calcular \(X = F^{-1}(U)\).

6.3 Exemplo 1

Seja \(X\) uma v.a. com: \[ F(x) = x^n, \quad \text{para } 0 < x < 1. \]

A função inversa é: \[ u = F(x) = x^n \implies x = u^{1/n}. \]

Portanto, o pseudo-algoritmo para gerar \(X\) a partir do método da inversão é:

  1. Gere \(U \sim \text{Unif}(0,1)\).

  2. Calcule \(X = U^{1/n}\).


Mostrar código
# Carregar a biblioteca ggplot2
library(ggplot2)

# Definir o parâmetro n da distribuição F(x) = x^n
n <- 3

# Gerar 1000 valores U de uma distribuição uniforme (0,1)
U <- runif(1000, min = 0, max = 1)

# Calcular X = U^(1/n)
X <- U^(1/n)

# Criar um dataframe para o ggplot2
data <- data.frame(X = X)

# Plotar o histograma usando ggplot2
p <- ggplot(data, aes(x = X)) +
  geom_histogram(aes(y = ..density..), bins = 30, fill = 'skyblue', color = 'black') +
  labs(title = 'Histograma de variáveis geradas pela inversão: F(x) = x^n, n = 3',
       x = 'Valor de X', y = 'Frequência') +
  theme_minimal() +
  theme(plot.title = element_text(size = 14),
        axis.title.x = element_text(size = 12),
        axis.title.y = element_text(size = 12))

# Exibir o gráfico
print(p)

Mostrar código
import numpy as np
import matplotlib.pyplot as plt

# Parâmetro n da distribuição F(x) = x^n
n = 3

# Gerando 1000 valores U de uma distribuição uniforme (0,1)
U = np.random.uniform(0, 1, 1000)

# Calculando X = U^(1/n)
X = U**(1/n)

# Plotando um histograma dos valores gerados
plt.figure(figsize=(10, 6))
plt.hist(X, bins=30, color='skyblue', edgecolor='black', density=True)
plt.title('Histograma de variáveis geradas pela inversão: F(x) = x^n, n = 3')
plt.xlabel('Valor de X')
plt.ylabel('Frequência')
plt.grid(True)
plt.show()

6.3.1 Exemplo 2

Seja \(X \sim \text{Exp}(\lambda)\), com: \[ F(x) = 1 - e^{-\lambda x}, \quad \text{para } x > 0. \]

A função inversa é: \[ u = F(x) = 1 - e^{-\lambda x} \implies x = -\frac{\log(1 - u)}{\lambda}. \]

Um pseudo-algoritmo para gerar \(X\) é, portanto,:

  1. Gere \(U \sim \text{Unif}(0,1)\).

  2. Calcule \(X = -\frac{\log(1 - U)}{\lambda}\).

Mostrar código
# Carregar a biblioteca ggplot2
library(ggplot2)

# Definir o parâmetro lambda da distribuição exponencial
lambda <- 2

# Gerar 1000 valores U de uma distribuição uniforme (0,1)
U <- runif(1000, min = 0, max = 1)

# Calcular X usando a inversa da CDF da distribuição exponencial
X <- -log(1 - U) / lambda

# Criar um dataframe para o ggplot2
data <- data.frame(X = X)

# Plotar o histograma usando ggplot2
p <- ggplot(data, aes(x = X)) +
  geom_histogram(aes(y = ..density..), bins = 30, fill = 'lightcoral', color = 'black') +
  labs(title = 'Histograma de variáveis geradas pela inversão: Distribuição Exponencial',
       x = 'Valor de X', y = 'Frequência') +
  theme_minimal() +
  theme(plot.title = element_text(size = 14),
        axis.title.x = element_text(size = 12),
        axis.title.y = element_text(size = 12))

# Exibir o gráfico
print(p)

Mostrar código
import numpy as np
import matplotlib.pyplot as plt

# Parâmetro lambda da distribuição exponencial
lambd = 2

# Gerando 1000 valores U de uma distribuição uniforme (0,1)
U = np.random.uniform(0, 1, 1000)

# Calculando X usando a inversa da CDF da exponencial
X = -np.log(1 - U) / lambd

# Plotando um histograma dos valores gerados
plt.figure(figsize=(10, 6))
plt.hist(X, bins=30, color='lightcoral', edgecolor='black', density=True)
plt.title('Histograma de variáveis geradas pela inversão: Distribuição Exponencial')
plt.xlabel('Valor de X')
plt.ylabel('Frequência')
plt.grid(True)
plt.show()

6.4 Simulação de transformações de variáveis aleatórias

Agora que já sabemos uma maneira de simular uma variável aleatória \(X\), descreveremos como gerar valores de uma transformação dessa variável, ou seja, \(g(X)\). Para isso, basta aplicar a função de transformação \(g\) diretamente aos valores simulados de \(X\). Veremos a seguinte alguns exemplos disso em funcionamento.


6.4.1 Exemplo 1: Simulando \(Y \sim Unif(1, 2)\)

Para gerar valores de \(Y \sim Unif(1, 2)\), usamos o fato de que \(Y\) é uma simples transformação de \(U \sim Unif(0, 1)\). A relação é: \[ Y = U + 1. \]

Assim, podemos usar o seguinte pseudo-algoritmo para gerar \(Y\) a partir de \(U\):

  1. Gere \(U \sim Unif(0,1)\).

  2. Calcule \(Y = U + 1\).

Mostrar código
# Carregar biblioteca ggplot2
library(ggplot2)

# Gerar 1000 valores U de uma distribuição uniforme (0,1)
U <- runif(1000, min = 0, max = 1)

# Calcular Y = U + 1 para ter Y ~ Unif(1, 2)
Y <- U + 1

# Criar um dataframe para o ggplot2
data <- data.frame(Y = Y)

# Plotar o histograma usando ggplot2
p <- ggplot(data, aes(x = Y)) +
  geom_histogram(aes(y = ..density..), bins = 30, fill = 'skyblue', color = 'black') +
  labs(title = 'Histograma de variáveis geradas: Y ~ Unif(1, 2)',
       x = 'Valor de Y', y = 'Frequência') +
  theme_minimal() +
  theme(plot.title = element_text(size = 14),
        axis.title.x = element_text(size = 12),
        axis.title.y = element_text(size = 12))

# Exibir o gráfico
print(p)

Mostrar código
import numpy as np
import matplotlib.pyplot as plt

# Gerando 1000 valores U de uma distribuição uniforme (0,1)
U = np.random.uniform(0, 1, 1000)

# Calculando Y = U + 1 para ter Y ~ Unif(1, 2)
Y = U + 1

# Plotando um histograma dos valores gerados
plt.figure(figsize=(10, 6))
plt.hist(Y, bins=30, color='skyblue', edgecolor='black', density=True)
plt.title('Histograma de variáveis geradas: Y ~ Unif(1, 2)')
plt.xlabel('Valor de Y')
plt.ylabel('Frequência')
plt.grid(True)
plt.show()

6.4.2 Exemplo 2: Simulando \(Y \sim Gamma(n, \lambda)\)

Para gerar valores de \(Y \sim \Gamma(n, \lambda)\), usamos o fato de que a soma de que \(Y\) pode ser representado como \[Y= \sum_{i=1}^n X_i,\] em que cada \(X_i \sim Exp(\lambda)\), e \(X_i\)’s são independentes.

Assim, podemos gerar \(Y\) da seguinte forma:

  1. Gere \(U_1, \dots, U_n \sim Unif(0,1)\) independentemente.

  2. Calcule \(X_i = -\frac{\log(1 - U_i)}{\lambda}\) para \(i = 1, \dots, n\).

  3. Calcule \(Y = X_1 + X_2 + \dots + X_n\).

Mostrar código
# Carregar biblioteca ggplot2
library(ggplot2)

# Definir parâmetros
n <- 5  # número de somas
lambda <- 2  # parâmetro da distribuição exponencial

# Gerar 1000 valores U para cada uma das n somas
U <- matrix(runif(1000 * n, min = 0, max = 1), ncol = n)

# Calcular X_i = -log(1 - U_i) / lambda para cada U_i
X <- -log(1 - U) / lambda

# Somar os valores de X para obter Y ~ Gamma(n, lambda)
Y <- rowSums(X)

# Criar um dataframe para o ggplot2
data <- data.frame(Y = Y)

# Plotar o histograma usando ggplot2
p <- ggplot(data, aes(x = Y)) +
  geom_histogram(aes(y = ..density..), bins = 30, fill = 'lightcoral', color = 'black') +
  labs(title = paste('Histograma de variáveis geradas: Y ~ Gamma(', n, ', ', lambda, ')'),
       x = 'Valor de Y', y = 'Frequência') +
  theme_minimal() +
  theme(plot.title = element_text(size = 14),
        axis.title.x = element_text(size = 12),
        axis.title.y = element_text(size = 12))

# Exibir o gráfico
print(p)

Mostrar código
import numpy as np
import matplotlib.pyplot as plt



# Definindo parâmetros
n = 5  # número de somas
lambd = 2  # parâmetro da distribuição exponencial

# Gerando 1000 valores U para cada uma das n somas
U = np.random.uniform(0, 1, (1000, n))

# Calculando X_i = -log(1 - U_i) / lambda para cada U_i
X = -np.log(1 - U) / lambd

# Somando os valores de X para obter Y ~ Gamma(n, lambda)
Y = np.sum(X, axis=1)

# Plotando um histograma dos valores gerados
plt.figure(figsize=(10, 6))
plt.hist(Y, bins=30, color='lightcoral', edgecolor='black', density=True)
plt.title(f'Histograma de variáveis geradas: Y ~ Gamma({n}, {lambd})')
plt.xlabel('Valor de Y')
plt.ylabel('Frequência')
plt.grid(True)
plt.show()

6.5 Exercícios

Exercício 1.

Utilizando o método da inversão, simule \(U \sim U(1,3)\).

Exercício 2.

  1. Implemente uma função para gerar uma amostra de tamanho \(n\) da distribuição Exponencial de parâmetro \(\lambda\).

  2. Compare a distribuição empírica dos valores simulados com a densidade da Exponencial \(f(x)=\lambda e^{-\lambda x}, x>0\).

Exercício 3.

  1. Implemente uma função para gerar uma amostra de tamanho \(n\) da distribuição \(Gama(a,b)\), para \(a\) sendo um valor inteiro.

  2. Compare a distribuição empírica dos valores simulados com a densidade da Gama \(f(x)=\frac{b^a}{\Gamma(a)}x^{a-1}e^{-bx}, x>0\).

Exercício 4. Seja \(X\) uma v.a. com função densidade dada por:

\[f(x) = \frac{1}{8}x,\quad 0 < x < 4.\]

  1. Escreva um pseudo-algoritmo para simular um único valor da variável \(X\) pelo método da inversão.

  2. Compare a distribuição empírica dos valores simulados com a densidade de \(X\).