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
20 visitas
perguntada Jul 2 em Estatística por Pedro Gomes (16 pontos)  
Compartilhe
comentou Jul 3 por danielcajueiro (5,566 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 6 dias atrás por Pedro Gomes (16 pontos)  
Estava com algumas dificuldades para colocar as formulas por isso colei as imagens, mas já consegui ajustar.
comentou 6 dias atrás por Pablo Castro (281 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!
...