Análise bayesiana hierárquica sobre diferenças de proporções

8

Por que hierárquico? : Tentei pesquisar esse problema e, pelo que entendi, esse é um problema "hierárquico", porque você está fazendo observações sobre observações de uma população, em vez de fazer observações diretas dessa população. Referência: http://www.econ.umn.edu/~bajari/iosp07/rossi1.pdf

Por que bayesiano? : Também o marquei como bayesiano porque uma solução assintótica / freqüentista pode existir para um "design experimental" em que cada "célula" recebe observações suficientes, mas para fins práticos conjuntos de dados do mundo real / não-experimental (ou em menos minha) são escassamente povoadas. Há muitos dados agregados, mas as células individuais podem ficar em branco ou ter apenas algumas observações.

O modelo em resumo:

Seja U uma população de unidades para cada uma das quais podemos aplicar um tratamento, , de ou , e de cada uma das quais observamos observações de 1 ou 0 aka sucessos e fracassos. Seja para a probabilidade de uma observação do objeto sob tratamento resultar em sucesso. Observe que pode estar correlacionado com . TAB p i T i{1 ...N}iT p i A p i Bu1,u2,u3...uNTABpiTi{1...N}iTpiApiB

Para viabilizar a análise, (a) assumimos que as distribuições e são uma instância de uma família específica de distribuições, como a distribuição beta, (b) e selecionamos algumas distribuições anteriores para hiperparâmetros.p BpApB

Exemplo do modelo

Eu tenho um saco muito grande de Magic 8 Balls. Cada bola 8, quando sacudida, pode revelar "Sim" ou "Não". Além disso, posso sacudi-los com a bola do lado direito para cima ou de cabeça para baixo (supondo que as nossas Magic 8 Balls trabalhem de cabeça para baixo ...). A orientação da bola pode mudar completamente a probabilidade de resultar em "Sim" ou "Não" (em outras palavras, inicialmente você não acredita que esteja correlacionado com ). p i BpiApiB

Questões:

Alguém amostrados aleatoriamente um número, , de unidades da população, e para cada uma das unidades tenha tomado e registado um número arbitrário de observações sob tratamento e um número arbitrário de observações sob tratamento . (Na prática, em nosso conjunto de dados, a maioria das unidades terá observações apenas sob um tratamento)A BnAB

Dados esses dados, preciso responder às seguintes perguntas:

  1. Se eu pegar uma nova unidade aleatoriamente da população, como posso calcular (analítica ou estocisticamente) a distribuição posterior da articulação de e ? (Principalmente para que possamos determinar a diferença esperada em proporções, )p x A p x B Δ = p x A - p x BuxpxApxBΔ=pxApxB
  2. Para uma unidade específica , , com observações de sucessos e falhas, como posso calcular (analítica ou estocástica) a distribuição posterior da articulação para e , novamente para criar uma distribuição da diferença de proporções y { 1 , 2 , 3 ... , n } s y f y p y A p y B Δ y p y A - p y Buyy{1,2,3...,n}syfypyApyBΔypyApyB

Pergunta de bônus: Embora realmente esperemos que e estejam muito correlacionados, não estamos modelando explicitamente isso. No provável caso de uma solução estocástica, acredito que isso faria com que alguns amostradores, incluindo Gibbs, fossem menos eficazes na exploração da distribuição posterior. É esse o caso? Em caso afirmativo, devemos usar um amostrador diferente, modelar a correlação como uma variável separada e transformar as distribuições para torná-las não correlacionadas ou apenas executar o amostrador por mais tempo?p B ppApBp

Critérios de resposta

Estou procurando uma resposta que:

  • Possui código, usando preferencialmente Python / PyMC, ou barrando JAGS que eu posso executar

  • É capaz de lidar com uma entrada de milhares de unidades

  • Dadas unidades e amostras suficientes, é capaz de distribuições para , e como resposta à pergunta 1, que podem ser mostradas para corresponder às distribuições de população subjacentes (a serem verificadas nas planilhas do Excel fornecidas nos "conjuntos de dados de desafio" seção)p B ΔpApBΔ

  • Dadas unidades e amostras suficientes, é capaz de produzir as distribuições corretas para , e (usarei as planilhas do Excel fornecidas na seção "conjuntos de dados de desafio" para verificar) como resposta à pergunta 2 e fornece algumas justificativa de por que essas distribuições estão corretasp B ΔpApBΔ

  • Se a resposta for semelhante ao último modelo JAGS que eu postei, explique por que funciona com anteriores, dpar(0.5,1)mas não com anteriores dgamma(2,20). Obrigado a Martyn Plummer no fórum JAGS por capturar o erro no meu modelo JAGS. Ao tentar definir um prior de Gamma (Shape = 2, Scale = 20), eu estava ligando para dgamma(2,20)definir um prior de Gamma (Shape = 2, InverseScale = 20) = Gamma (Shape = 2, Scale = 0,05).

Conjuntos de dados de desafio

Gerei alguns exemplos de conjuntos de dados no Excel, com alguns cenários possíveis diferentes, alterando a rigidez das distribuições p, a correlação entre elas e facilitando a alteração de outras entradas. https://docs.google.com/file/d/0B_rPBjs4Cp0zLVBybU1nVnd0ZFU/edit?usp=sharing (~ 8 MB)

Uma visualização dos 4 conjuntos de dados incluídos no arquivo do Excel

Minhas tentativas / soluções parciais até o momento

1) Eu baixei e instalei o Python 2.7 e o PyMC 2.2. Inicialmente, obtive um modelo incorreto para executar, mas quando tentei reformular o modelo, a extensão congela. Ao adicionar / remover o código, determinei que o código que aciona o congelamento é mc.Binomial (...), embora essa função tenha funcionado no primeiro modelo, presumo que haja algo errado com a forma como especifiquei o modelo.

import pymc as mc
import numpy as np
import scipy.stats as stats
from __future__ import division
cases=[0,0]
for case in range(2):
    if case==0:
        # Taken from the sample datasets excel sheet, Focused Correlated p's
        c_A_arr, n_A_arr, c_B_arr, n_B_arr=np.loadtxt("data/TightCorr.tsv", unpack=True)

    if case==1:
        # Taken from the sample datasets excel sheet, Focused Uncorrelated p's
        c_A_arr, n_A_arr, c_B_arr, n_B_arr=np.loadtxt("data/TightUncorr.tsv", unpack=True)

    scale=20.0
    alpha_A=mc.Uniform("alpha_A", 1,scale)
    beta_A=mc.Uniform("beta_A", 1,scale)
    alpha_B=mc.Uniform("alpha_B", 1,scale)
    beta_B=mc.Uniform("beta_B", 1,scale)
    p_A=mc.Beta("p_A",alpha=alpha_A,beta=beta_A)
    p_B=mc.Beta("p_B",alpha=alpha_B,beta=beta_B)

    @mc.deterministic
    def delta(p_A=p_A,p_B=p_B):
        return p_A-p_B

    obs_n_A=mc.DiscreteUniform("obs_n_A",lower=0,upper=20,observed=True, value=n_A_arr)
    obs_n_B=mc.DiscreteUniform("obs_n_B",lower=0,upper=20,observed=True, value=n_B_arr)

    obs_c_A=mc.Binomial("obs_c_A",n=obs_n_A,p=p_A, observed=True, value=c_A_arr)
    obs_c_B=mc.Binomial("obs_c_B",n=obs_n_B,p=p_B, observed=True, value=c_B_arr)


    model = mc.Model([alpha_A,beta_A,alpha_B,beta_B,p_A,p_B,delta,obs_n_A,obs_n_B,obs_c_A,obs_c_B])
    cases[case] = mc.MCMC(model)
    cases[case].sample(24000, 12000, 2)

    lift_samples = cases[case].trace('delta')[:]

    ax = plt.subplot(211+case)
    figsize(12.5,5)
    plt.title("Posterior distributions of lift from 0 to T")
    plt.hist(lift_samples, histtype='stepfilled', bins=30, alpha=0.8,
             label="posterior of lift", color="#7A68A6", normed=True)
    plt.vlines(0, 0, 4, color="k", linestyles="--", lw=1)
    plt.xlim([-1, 1])

2) Eu baixei e instalei o JAGS 3.4. Depois de obter uma correção nos meus anteriores no fórum JAGS, agora tenho este modelo, que é executado com êxito:

Modelo

var alpha_A, beta_A, alpha_B, beta_B, p_A[N], p_B[N], delta[N], n_A[N], n_B[N], c_A[N], c_B[N];
model {
    for (i in 1:N) {
        c_A[i] ~ dbin(p_A[i],n_A[i])
        c_B[i] ~ dbin(p_B[i],n_B[i])
        p_A[i] ~ dbeta(alpha_A,beta_A)
        p_B[i] ~ dbeta(alpha_B,beta_B)
        delta[i] <- p_A[i]-p_B[i]
    }
    alpha_A ~ dgamma(1,0.05)
    alpha_B ~ dgamma(1,0.05)
    beta_A ~ dgamma(1,0.05)
    beta_B ~ dgamma(1,0.05)
}

Dados

"N" <- 60
"c_A" <- structure(c(0,6,0,3,0,8,0,4,0,6,1,5,0,5,0,7,0,3,0,7,0,4,0,5,0,4,0,5,0,4,0,2,0,4,0,5,0,8,2,7,0,6,0,3,0,3,0,8,0,4,0,4,2,6,0,7,0,3,0,1))
"c_B" <- structure(c(5,0,2,2,2,0,2,0,2,0,0,0,5,0,4,0,3,1,2,0,2,0,2,0,0,0,3,0,6,0,4,1,5,0,2,0,6,0,1,0,2,0,4,0,4,1,1,0,3,0,5,0,0,0,5,0,2,0,7,1))
"n_A" <- structure(c(0,9,0,3,0,9,0,9,0,9,3,9,0,9,0,9,0,3,0,9,0,9,0,9,3,9,0,9,0,9,0,3,0,9,0,9,0,9,3,9,0,9,0,9,0,3,0,9,0,9,0,9,3,9,0,9,0,9,0,3))
"n_B" <- structure(c(9,0,9,3,9,0,9,0,9,0,3,0,9,0,9,0,9,3,9,0,9,0,9,0,3,0,9,0,9,0,9,3,9,0,9,0,9,0,3,0,9,0,9,0,9,3,9,0,9,0,9,0,3,0,9,0,9,0,9,3))

Ao controle

model in Try1.bug
data in Try1.r
compile, nchains(2)
initialize
update 400
monitor set p_A, thin(3)
monitor set p_B, thin(3)
monitor set delta, thin(3)
update 1000
coda *, stem(Try1)

A aplicação real para quem prefere escolher o modelo :)

Na web, o teste A / B típico considera o impacto na taxa de conversão de uma única página ou unidade de conteúdo, com possíveis variações. As soluções típicas incluem um teste de significância clássico em relação às hipóteses nulas ou duas proporções iguais, ou mais recentemente soluções bayesianas analíticas que alavancam a distribuição beta como um conjugado anterior.

Em vez dessa abordagem de unidade única de conteúdo, que, aliás, exigiria muitos visitantes de cada unidade da qual estou interessado em testar, queremos comparar variações em um processo que gera várias unidades de conteúdo (não é realmente um cenário incomum) ...) Portanto, no geral, as unidades / páginas produzidas pelo processo A ou B têm muitas visitas / dados, mas cada unidade individual pode ter apenas algumas observações.

Fabio Beltramini
fonte
Você pulou aspectos cruciais em sua descrição. Depois de desenhar uniformemente um , o que acontece a seguir? Algo deve, pois caso contrário você não tem absolutamente nenhuma informação sobre qualquer um dos ! Então, o que você observa? Você observa e, digamos, um empate independente de ? Ou você apenas observa o sorteio de e não registra ? Para estimar todas essas distribuições de densidade, certamente você deve repetir o processo muitas e muitas vezes - quantas? Ou, por "estimativa", você supõe que conhece todos os e gostaria de calcular a distribuição do resultado de sua experiência? p x x O x o x x p xxpxxoxoxxpx
whuber
Desculpe, talvez a frase " seja uniformemente extraída de 1 ... N" tenha sido enganosa. Dado um grande número de observações existentes sobre vários , quero determinar a distribuição de . É um pouco análogo à amostragem de 50 pessoas de uma população, observando suas alturas e, em seguida, solicitando a distribuição da altura para uma pessoa "sorteada aleatoriamente da população". Eu apenas usei uniforme, já que a população nesse caso foi enumerada e vejo que é confusa. (Continuando com a analogia, neste cenário, não consegue medir o povo, apenas observar algumas respostas binários)o x p xxoxpx
Fabio Beltramini
Adicionei um exemplo ao final da pergunta que, com sorte, deixa claro o que estou tentando fazer.
Fabio Beltramini 28/08
Obrigado. A questão permanece confusa, no entanto. No exemplo, você está observando um par ordenado de valores: tempos rolados e sucessos. Exatamente sobre o que "distribuição" você está perguntando? Precisamente a que propriedade do grande saco de dados ela corresponderia?
whuber
1
O par de valores (rolos e sucessos) transmite informações sobre uma variável latente, p. A distribuição que eu quero é a distribuição de p's na sacola. Obviamente, se não assumirmos uma classe de distribuições a que ela pertence, existem arbitrariamente muitas possibilidades, mas se dissermos que p é, por exemplo, distribuído por beta, então tudo se resume a selecionar apenas os melhores parâmetros de ajuste para isso. classe de distribuições. Se ajudar, agora considere, em vez de dados com p = 1 / 4,1 / 6,1 / 8, que cada objeto tenha um p de Beta (2,2) ... ou Beta (4,4), etc.
Fabio Beltramini

Respostas:

2

Como o tempo para a recompensa expirou e eu não recebi respostas, postarei a resposta que consegui, embora minha experiência limitada com inferência bayesiana sugira que isso deva ser tomado com uma dose saudável de ceticismo.

I) Configuração

  1. Baixei e instalei o JAGS 3.4 e R 3.0.1
  2. Instalei os pacotes rjags e coda iniciando o R e usando install.packages (pkgname)

II) Modelo e dados - Utilizou os arquivos de modelo e dados já detalhados na pergunta. Para responder à pergunta 1, adicionei uma observação adicional aos dados com todas as quatro variáveis ​​como 0.

III) Respondendo perguntas

  1. Eu executei o JAGS no modelo / data (abra a linha de comando, acesse o diretório com seus arquivos e digite> jags-terminal Command.cmd. Ele executou e produziu alguns arquivos
  2. No R, usei os seguintes comandos:
    • biblioteca ("rjags") para carregar o pacote instalado (e sua coda de pacote necessária)
    • setwd () para chegar ao diretório em que os arquivos de saída estavam
    • resultados = read.coda ("STEMchain1.txt", "STEMindex.txt")
  3. Para responder à primeira pergunta:
    • Como um gráfico em PDF, "gráfico (resultados [, 3 * N])"
    • Como quantis, "quantil (resultados [, 3 * N], c (0.025,0.25,0.5,0.75,0.975))"
    • Onde N é o número de observações e a última observação corresponde à posição da observação "todos os 0". (1 a n é para a variável p_A, n + 1 a 2n é para p_B e 2n + 1 a 3n é para delta)
  4. Para responder à segunda pergunta, o mesmo que acima, mas altere 3 * N -> 2 * N + y

Não tenho certeza se essa é a maneira correta de obter a resposta, ou se um modelo mais complexo produziria melhores resultados, principalmente no caso de correlação, mas espero que, eventualmente, alguém com mais experiência apareça ...

Fabio Beltramini
fonte