Bayesian setara dengan dua sampel t-test?

39

Saya tidak mencari metode plug and play seperti BEST in R melainkan penjelasan matematis tentang beberapa metode Bayesian yang dapat saya gunakan untuk menguji perbedaan antara rata-rata dua sampel.

John
sumber
15
makalah TERBAIK asli mungkin apa yang Anda cari: indiana.edu/~kruschke/BEST/BEST.pdf
Cam.Davidson.Pilon
4
Untuk memperjelas, apakah kita berbicara tentang uji dua sampel yang setara dengan uji sering perbedaan rata-rata dalam dua kelompok, seperti uji-t? atau Anda tertarik pada pengujian hipotesis nol yang kuat untuk perbedaan distribusi seperti tes Kolmogorov-Smirnoff?
AdamO

Jawaban:

46

Ini adalah pertanyaan yang bagus, yang sepertinya banyak muncul: tautan 1 , tautan 2 . Kertas Bayesian Estimation Superseeds the T-Test yang ditunjukkan Cam.Davidson.Pilon adalah sumber yang bagus untuk subjek ini. Ini juga sangat baru, diterbitkan pada 2012, yang saya pikir sebagian karena minat saat ini di daerah tersebut.

Saya akan mencoba merangkum penjelasan matematis dari alternatif Bayesian untuk dua sampel t-test. Ringkasan ini mirip dengan makalah TERBAIK yang menilai perbedaan dalam dua sampel dengan membandingkan perbedaan dalam distribusi posterior mereka (dijelaskan di bawah dalam R).

set.seed(7)

#create samples
sample.1 <- rnorm(8, 100, 3)
sample.2 <- rnorm(10, 103, 7)

#we need a pooled data set for estimating parameters in the prior.
pooled <- c(sample.1, sample.2)
par(mfrow=c(1, 2))

hist(sample.1)
hist(sample.2)

masukkan deskripsi gambar di sini

Untuk membandingkan sampel berarti kita perlu memperkirakan jumlahnya. Metode Bayesian untuk melakukannya menggunakan teorema Bayes: P (A | B) = P (B | A) * P (A) / P (B) (sintaks dari P (A | B) dibaca sebagai probabilitas dari A diberikan B)

, posterior sebanding dengan kemungkinan kali sebelumnya

P(meSebuahn.1|sSebuahmhalle.1) P(sSebuahmhalle.1|meSebuahn.1)P(meSebuahn.1)P(sSebuahmhalle.1|meSebuahn.1)P(meSebuahn.1)

Mari kita letakkan dalam kode. Kode membuat segalanya lebih baik.

likelihood <- function(parameters){
  mu1=parameters[1]; sig1=parameters[2]; mu2=parameters[3]; sig2=parameters[4]
  prod(dnorm(sample.1, mu1, sig1)) * prod(dnorm(sample.2, mu2, sig2))
}

prior <- function(parameters){
  mu1=parameters[1]; sig1=parameters[2]; mu2=parameters[3]; sig2=parameters[4]
  dnorm(mu1, mean(pooled), 1000*sd(pooled)) * dnorm(mu2, mean(pooled), 1000*sd(pooled)) * dexp(sig1, rate=0.1) * dexp(sig2, 0.1)
}

Saya membuat beberapa asumsi sebelumnya yang perlu dibenarkan. Untuk menjaga agar para prior tidak berprasangka terhadap perkiraan rata-rata, saya ingin menjadikannya luas dan seragam atas nilai-nilai yang masuk akal dengan tujuan membiarkan data menghasilkan fitur-fitur posterior. Saya menggunakan pengaturan yang disarankan dari BEST dan mendistribusikan mu secara normal dengan mean = mean (pooled) dan deviasi standar luas = 1000 * sd (pooled). Penyimpangan standar yang saya tetapkan untuk distribusi eksponensial yang luas, karena saya ingin distribusi tanpa batas yang luas.

Sekarang kita bisa membuat posterior

posterior <- function(parameters) {likelihood(parameters) * prior(parameters)}

Kami akan mencicipi distribusi posterior menggunakan rantai markov monte carlo (MCMC) dengan modifikasi Metropolis Hastings. Paling mudah dipahami dengan kode.

#starting values
mu1 = 100; sig1 = 10; mu2 = 100; sig2 = 10
parameters <- c(mu1, sig1, mu2, sig2)

#this is the MCMC /w Metropolis method
n.iter <- 10000
results <- matrix(0, nrow=n.iter, ncol=4)
results[1, ] <- parameters
for (iteration in 2:n.iter){
  candidate <- parameters + rnorm(4, sd=0.5)
  ratio <- posterior(candidate)/posterior(parameters)
  if (runif(1) < ratio) parameters <- candidate #Metropolis modification
  results[iteration, ] <- parameters
}

Matriks hasil adalah daftar sampel dari distribusi posterior untuk setiap parameter yang dapat kita gunakan untuk menjawab pertanyaan awal kita: Apakah sampel.1 berbeda dari sampel.2? Tetapi pertama-tama untuk menghindari pengaruh dari nilai awal kita akan "membakar" 500 nilai pertama rantai.

#burn-in
results <- results[500:n.iter,]

Sekarang, apakah sampel.1 berbeda dari sampel.2?

mu1 <- results[,1]
mu2 <- results[,3]

hist(mu1 - mu2)

masukkan deskripsi gambar di sini

mean(mu1 - mu2 < 0)
[1] 0.9953689

Dari analisis ini saya akan menyimpulkan ada kemungkinan 99,5% bahwa rata-rata untuk sampel.1 kurang dari rata-rata untuk sampel.2.

Keuntungan dari pendekatan Bayesian, sebagaimana ditunjukkan dalam makalah TERBAIK, adalah dapat membuat teori yang kuat. EG berapa probabilitas bahwa sampel.2 adalah 5 unit lebih besar dari sampel.1.

mean(mu2 - mu1 > 5)
[1] 0.9321124

Kami akan menyimpulkan bahwa ada kemungkinan 93% bahwa rata-rata sampel.2 adalah 5 unit lebih besar dari sampel.1. Pembaca yang taat akan menemukan hal yang menarik karena kita tahu populasi sebenarnya memiliki sarana masing-masing 100 dan 103. Ini kemungkinan besar disebabkan oleh ukuran sampel yang kecil, dan pilihan untuk menggunakan distribusi normal untuk kemungkinan tersebut.

Saya akan mengakhiri jawaban ini dengan peringatan: Kode ini untuk tujuan pengajaran. Untuk analisis nyata, gunakan RJAGS dan tergantung pada ukuran sampel Anda, pasangkan distribusi-t untuk kemungkinan tersebut. Jika ada minat saya akan memposting uji-t menggunakan RJAGS.

EDIT: Seperti yang diminta di sini adalah model JAGS.

model.str <- 'model {
    for (i in 1:Ntotal) {
        y[i] ~ dt(mu[x[i]], tau[x[i]], nu)
    }
    for (j in 1:2) {
        mu[j] ~ dnorm(mu_pooled, tau_pooled)
        tau[j] <- 1 / pow(sigma[j], 2)
        sigma[j] ~ dunif(sigma_low, sigma_high)
    }
    nu <- nu_minus_one + 1
    nu_minus_one ~ dexp(1 / 29)
}'

# Indicator variable
x <- c(rep(1, length(sample.1)), rep(2, length(sample.2)))

cpd.model <- jags.model(textConnection(model.str),
                        data=list(y=pooled,
                                  x=x,
                                  mu_pooled=mean(pooled),
                                  tau_pooled=1/(1000 * sd(pooled))^2,
                                  sigma_low=sd(pooled) / 1000,
                                  sigma_high=sd(pooled) * 1000,
                                  Ntotal=length(pooled)))
update(cpd.model, 1000)
chain <- coda.samples(model = cpd.model, n.iter = 100000,
                      variable.names = c('mu', 'sigma'))
rchain <- as.matrix(chain)
hist(rchain[, 'mu[1]'] - rchain[, 'mu[2]'])
mean(rchain[, 'mu[1]'] - rchain[, 'mu[2]'] < 0)
mean(rchain[, 'mu[2]'] - rchain[, 'mu[1]'] > 5)
pengguna1068430
sumber
Hanya ingin tahu apakah ada solusi yang masuk akal untuk menggunakan perbandingan dua sampel Bayesian dengan jenis set data ini. stackoverflow.com/q/57503523/7288088
pyring
7

Jawaban yang sangat baik oleh user1068430 diimplementasikan dalam Python

import numpy as np
from pylab import plt

def dnorm(x, mu, sig):
    return 1/(sig * np.sqrt(2 * np.pi)) * np.exp(-(x - mu)**2 / (2 * sig**2))

def dexp(x, l):
    return l * np.exp(- l*x)

def like(parameters):
    [mu1, sig1, mu2, sig2] = parameters
    return dnorm(sample1, mu1, sig1).prod()*dnorm(sample2, mu2, sig2).prod()

def prior(parameters):
    [mu1, sig1, mu2, sig2] = parameters
    return dnorm(mu1, pooled.mean(), 1000*pooled.std()) * dnorm(mu2, pooled.mean(), 1000*pooled.std()) * dexp(sig1, 0.1) * dexp(sig2, 0.1)

def posterior(parameters):
    [mu1, sig1, mu2, sig2] = parameters
    return like([mu1, sig1, mu2, sig2])*prior([mu1, sig1, mu2, sig2])


#create samples
sample1 = np.random.normal(100, 3, 8)
sample2 = np.random.normal(100, 7, 10)

pooled= np.append(sample1, sample2)

plt.figure(0)
plt.hist(sample1)
plt.hold(True)
plt.hist(sample2)
plt.show(block=False)

mu1 = 100 
sig1 = 10
mu2 = 100
sig2 = 10
parameters = np.array([mu1, sig1, mu2, sig2])

niter = 10000

results = np.zeros([niter, 4])
results[1,:] = parameters

for iteration in np.arange(2,niter):
    candidate = parameters + np.random.normal(0,0.5,4)
    ratio = posterior(candidate)/posterior(parameters)
    if np.random.uniform() < ratio:
        parameters = candidate
    results[iteration,:] = parameters

#burn-in
results = results[499:niter-1,:]

mu1 = results[:,1]
mu2 = results[:,3]

d = (mu1 - mu2)
p_value = np.mean(d > 0)

plt.figure(1)
plt.hist(d,normed = 1)
plt.show()
Francisco Grings
sumber
6

Dengan analisis Bayesian Anda memiliki lebih banyak hal untuk ditentukan (itu sebenarnya adalah hal yang baik, karena memberikan lebih banyak fleksibilitas dan kemampuan untuk memodelkan apa yang Anda yakini sebagai kebenaran). Apakah Anda mengasumsikan normals untuk kemungkinan? Apakah kedua grup memiliki varian yang sama?

Salah satu pendekatan lurus ke depan adalah untuk memodelkan 2 berarti (dan 1 atau 2 varian / dispersi) kemudian melihat posterior pada perbedaan 2 berarti dan / atau Interval Kredibel pada perbedaan 2 berarti.

Greg Snow
sumber
Bisakah Anda memberikan detail lebih lanjut tentang ini? Saya tidak yakin bagaimana cara memodelkan 2 berarti dan melihat eksterior.
John
4

penjelasan matematis tentang beberapa metode Bayesian yang dapat saya gunakan untuk menguji perbedaan antara rata-rata dua sampel.

Ada beberapa pendekatan untuk "menguji" ini. Saya akan menyebutkan pasangan:

  • Jika Anda menginginkan keputusan eksplisit, Anda bisa melihat teori keputusan.

  • Suatu hal yang cukup sederhana yang kadang-kadang dilakukan adalah menemukan interval untuk perbedaan dalam cara dan mempertimbangkan apakah itu termasuk 0 atau tidak. Itu akan melibatkan mulai dengan model untuk pengamatan, penentuan parameter dan perhitungan distribusi posterior dari perbedaan dalam cara yang tergantung pada data.

    Anda harus mengatakan apa model Anda (mis. Normal, varians konstan), dan kemudian (setidaknya) beberapa sebelum untuk perbedaan dalam mean dan sebelum untuk varians. Anda mungkin memiliki prior pada parameter dari prior tersebut pada gilirannya. Atau Anda mungkin tidak menganggap varian konstan. Atau Anda mungkin menganggap sesuatu selain dari normalitas.

Glen_b -Reinstate Monica
sumber