Primeira vez aqui? Seja bem vindo e cheque o FAQ!
x

Como utilizar o método de Varáveis Antiéticas para reduzir a variância em simulações Monte Carlo?

+1 voto
29 visitas
perguntada Jul 2 em Estatística por Pedro Gomes (16 pontos)  
Compartilhe
comentou Jul 3 por danielcajueiro (5,666 pontos)  
Oi Pedro!
Por favor, coloque a resposta abrindo uma aba de resposta. Vc colocou a resposta nos comentarios.
comentou Jul 3 por Pedro Gomes (16 pontos)  
Oi Daniel, está feito. Desculpa a confusão.

1 Resposta

0 votos
respondida Jul 3 por Pedro Gomes (16 pontos)  
editado Jul 3 por Pedro Gomes

Essa resposta está baseada em "Monte Carlo Methods - Malvin H. Kalos and Paula A. Whitlock" seção 4.4.

O método das variáveis antiéticas explora a queda da variância que ocorre quando variáveis aleatórias são correlacionadas negativamente.
Suponha a função a seguir:
\[ G=\int_{1}^{0} g(x)dx \]
Logo, G também pode ser escrito da seguinte maneira:
\[ G=\int_{1}^{0} \frac{1}{2}[g(x) + g(1 -x)dx \]
G pode ser avaliado via Monte Carlo selecionando x uniformemente entre 0 e 1, o valor de g(x) e g(1-x) é determinado e o estimador de G é formado:
\[ G_{N}=1/N \sum_{i=1}^{N}1/2[g(x_i )+g(1-x_i )] \]
Para funções lineares, esse metódo reduzirá a variância. Por exemplo considere a função exponencial \( G = \int_{0}^{1} e^{x}dx \) , a variância associada a uma avaliação Monte Carlo direta é de 0,243 e utilizando o estimador Gn com variáves antiéticas a variância é reduzida para 0,0035.

A imagem será apresentada aqui.
A imagem será apresentada aqui.

Essa técnica também pode ser combinada com outras técnicas para reduzir a variância, um exemplo é utilizar importance sampling, a função G se torna:
\[ G = \int_{0}^{1} \frac{1/2[g(x) - g(1-x)]}{f(x)}dx \]

Um f(x) aproximado para o exemplo é: \( f(x) = \frac{24}{25}[1 + \frac{1}{2}(x - \frac{1}{2})^2] \) . E a variância cai para 0,0000012.

A imagem será apresentada aqui.

Abaixo segue todo o código utilizado para conferir os exemplos.

import numpy as np
import math
import matplotlib.pyplot as plt

def var_strgh_mc(n):
    x = np.random.uniform(0,1,n)
    a = []
    for i in range(n):
        h_x = math.exp(x[i])
        a = np.append(a,h_x)
    GN = sum(a)/n
    var = np.var(a)

    return var, GN

def est_monte_carlo(n):
    x = np.random.uniform(0,1,n)
    a = []
    for i in range(n):    
        h_x = 0.5*(math.exp(x[i]) + math.exp(1-x[i]))
        #print(h_x)
        a = np.append(a,h_x)
    GN = sum(a)/n
    var = np.var(a)

    return var, GN


def ImpSamp_AnthVar(n):
    x = np.random.uniform(0,1,n)
    a = []
    for i in range(n):
        f_x = (24/25)*(1 + 0.5*((x[i] - 0.5)**(2)))
        h_x = 0.5*((math.exp(x[i]) + math.exp(1-x[i]))/f_x)
        a = np.append(a,h_x)
    GN = sum(a)/n
    var = np.var(a)

    return var, GN

if __name__ == '__main__':
    numeroAmostras=1000
    n=1000
    vetor_var = np.empty([numeroAmostras])
    vetor_GN = np.empty([numeroAmostras])    
    vetor_var1 = np.empty([numeroAmostras])
    vetor_GN1 = np.empty([numeroAmostras])
    vetor_var2 = np.empty([numeroAmostras])
    vetor_GN2 = np.empty([numeroAmostras])

    for i in range(0,numeroAmostras):
        [var, GN] = var_strgh_mc(n)
        [var1, GN1] = est_monte_carlo(n)
        [var2 , GN2] = ImpSamp_AnthVar(n)
        vetor_var[i] = var
        vetor_var1[i] = var1
        vetor_var2[i] = var2
        vetor_GN[i] = GN
        vetor_GN1[i] = GN1
        vetor_GN2[i] = GN2
    plt.figure(0)
    plt.hist(vetor_var)
    plt.figure(1)
    plt.hist(vetor_var1)
    plt.figure(2)
    plt.hist(vetor_var2)

    print('Variância função exponencial:',var)
    print('Variância com Variáveis Antiéticas:',var1)
    print('Variância com Var Antiéticas com Importance Sampling:', var2)
var_strgh_mc(n)
est_monte_carlo(n)
ImpSamp_AnthVar(n)
comentou Jul 3 por professor (331 pontos)  
Caro, por favor, considere a política de conduta descrita aqui:

http://prorum.com/?qa=2033/como-eu-posso-contribuir-para-o-prorum

"O que devo evitar no PRorum?: a - Colar imagens ao invés de fazer as perguntas. b - Colar imagens (usando scanner ou outro dispositivo) de livros ou outro materiais ao invés de escrever texto. c - Criar várias contas para manipular a pontuação de perguntas.
d - Colocar títulos inadequados nas perguntas, por exemplo, "Ajude-me", "help-me", "Atividade", "Pergunta". Como título coloque um resumo da pergunta. "
comentou Jul 12 por Pedro Gomes (16 pontos)  
Estava com algumas dificuldades para colocar as formulas por isso colei as imagens, mas já consegui ajustar.
comentou Jul 12 por Pablo Castro (286 pontos)  
Seu código ficou claro e replicável. Ótima solução, não conhecia este método para redução de variância no em simulações Monte-Carlo.

De fato, a uma enorme redução da variância. Adaptando os retornos das funções implementadas neste exercício (Return GN), podemos verificar isso graficamente, com o gráfico gerado com a seguinte implementação:

if __name__ == '__main__':
    n = 1000
    # print(var_strgh_mc(n))
    # print(est_monte_carlo(n))
    # print(ImpSamp_AnthVar(n))
    amostras = 10000
    domain = list(range(1, amostras+1))
    x = []
    y = []
    z = []
    for simulacao in range(1, amostras+1):
        x.append(var_strgh_mc(n))
        y.append(est_monte_carlo(n))
        z.append(ImpSamp_AnthVar(n))

    plt.xlabel('Simulações')
    plt.ylabel('Gn')
    plt.plot(domain, x, 'b.', domain, y, 'g.', domain, z, 'r.')
    plt.savefig('coment.png')

Os pontos azuis mostram as estatísticas GN da primeira função, os pontos verdes da segunda e os pontos vermelhos da terceira. É nítida a redução da variância. Muito legal!
...