Non sto cercando un metodo plug and play come BEST in R, ma piuttosto una spiegazione matematica di quali sono alcuni metodi bayesiani che posso usare per testare la differenza tra la media di due campioni.
Non sto cercando un metodo plug and play come BEST in R, ma piuttosto una spiegazione matematica di quali sono alcuni metodi bayesiani che posso usare per testare la differenza tra la media di due campioni.
Risposte:
Questa è una buona domanda, che sembra apparire molto: link 1 , link 2 . Il documento Bayesian Estimation sostituisce il T-Test che Cam.Davidson.Pilon ha sottolineato è un'ottima risorsa su questo argomento. È anche molto recente, pubblicato nel 2012, che ritengo in parte dovuto all'attuale interesse nell'area.
Proverò a riassumere una spiegazione matematica di un'alternativa bayesiana al test t di due campioni. Questo riassunto è simile al documento MIGLIORE che valuta la differenza in due campioni confrontando la differenza nelle loro distribuzioni posteriori (spiegata di seguito in 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)
Al fine di confrontare il campione significa che dobbiamo stimare ciò che sono. Il metodo bayesiano per farlo utilizza il teorema di Bayes: P (A | B) = P (B | A) * P (A) / P (B) (la sintassi di P (A | B) viene letta come probabilità di A dato B)
Grazie ai moderni metodi numerici possiamo ignorare la probabilità di B, P (B) e usare lo statuto proporzionale: P (A | B) P (B | A) * P (A) Nel vernacolo bayesiano il posteriore è proporzionale alla probabilità volte il precedente
Applicando la teoria di Bayes al nostro problema in cui vogliamo conoscere i mezzi dei campioni dati alcuni dati otteniamo . Il primo termine a destra è la probabilità, , che è la probabilità di osservare i dati del campione dati media.1. Il secondo termine è il precedente, , che è semplicemente la probabilità della media.1. Capire i priori appropriati è ancora un po 'un'arte ed è uno dei maggiori critici dei metodi bayesiani.
Mettiamolo nel codice. Il codice rende tutto migliore.
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)
}
In precedenza ho formulato alcune ipotesi che devono essere giustificate. Per evitare che i priori pregiudicassero la media stimata, volevo renderli ampi e uniformi su valori plausibili allo scopo di consentire ai dati di produrre le caratteristiche del posteriore. Ho usato l'impostazione consigliata da BEST e ho distribuito normalmente i mu con mean = mean (raggruppati) e un'ampia deviazione standard = 1000 * sd (raggruppati). Le deviazioni standard che ho impostato su un'ampia distribuzione esponenziale, perché volevo un'ampia distribuzione illimitata.
Ora possiamo rendere il posteriore
posterior <- function(parameters) {likelihood(parameters) * prior(parameters)}
Campioneremo la distribuzione posteriore usando una catena markov monte carlo (MCMC) con modifica di Metropolis Hastings. È più facile da capire con il codice.
#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
}
La matrice dei risultati è un elenco di campioni della distribuzione posteriore per ciascun parametro che possiamo usare per rispondere alla nostra domanda originale: sample.1 è diverso da sample.2? Ma prima per evitare gli affetti dai valori iniziali "bruceremo" i primi 500 valori della catena.
#burn-in
results <- results[500:n.iter,]
Ora, sample.1 è diverso da sample.2?
mu1 <- results[,1]
mu2 <- results[,3]
hist(mu1 - mu2)
mean(mu1 - mu2 < 0)
[1] 0.9953689
Da questa analisi, concluderei che esiste una probabilità del 99,5% che la media per il campione.1 sia inferiore alla media per il campione.2.
Un vantaggio dell'approccio bayesiano, come sottolineato nel documento BEST, è che può fare forti teorie. Ad esempio qual è la probabilità che sample.2 sia 5 unità più grande del sample.1.
mean(mu2 - mu1 > 5)
[1] 0.9321124
Concludiamo che esiste una probabilità del 93% che la media del campione.2 sia 5 unità maggiore del campione.1. Un lettore osservatore lo troverebbe interessante perché sappiamo che le popolazioni vere hanno mezzi rispettivamente di 100 e 103. Ciò è probabilmente dovuto alle dimensioni ridotte del campione e alla scelta di utilizzare una distribuzione normale per la probabilità.
Concluderò questa risposta con un avvertimento: questo codice è a scopo didattico. Per una vera analisi usa RJAGS e in base alla dimensione del tuo campione adatta una distribuzione a T per la probabilità. Se c'è interesse, posterò un test t usando RJAGS.
EDIT: come richiesto qui è un modello 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)
L'eccellente risposta dell'utente 1068430 implementata in 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()
Con un'analisi bayesiana hai più cose da specificare (che in realtà è una buona cosa, dal momento che offre molta più flessibilità e capacità di modellare ciò che ritieni sia la verità). Stai assumendo normali per le probabilità? I 2 gruppi avranno la stessa varianza?
Un approccio diretto è quello di modellare i 2 mezzi (e 1 o 2 varianze / dispersioni), quindi guardare il posteriore sulla differenza dei 2 mezzi e / o l'intervallo credibile sulla differenza dei 2 mezzi.
una spiegazione matematica di quali sono alcuni metodi bayesiani che posso usare per testare la differenza tra la media di due campioni.
Esistono diversi approcci per "testare" questo. Ne citerò un paio:
Se si desidera una decisione esplicita , è possibile esaminare la teoria delle decisioni.
Una cosa abbastanza semplice che a volte viene fatta è trovare un intervallo per la differenza nei mezzi e considerare se include 0 o meno. Ciò implicherebbe iniziare con un modello per le osservazioni, i priori sui parametri e il calcolo della distribuzione posteriore della differenza nei mezzi in base ai dati.
Dovresti dire qual è il tuo modello (ad es. Varianza normale e costante) e poi (almeno) alcuni precedenti per la differenza di mezzi e un precedente per la varianza. Potresti avere a priori i parametri di quei priori a loro volta. Oppure potresti non assumere una varianza costante. Oppure potresti assumere qualcosa di diverso dalla normalità.