No busco un método plug and play como BEST in R, sino una explicación matemática de cuáles son algunos métodos bayesianos que puedo usar para probar la diferencia entre la media de dos muestras.
No busco un método plug and play como BEST in R, sino una explicación matemática de cuáles son algunos métodos bayesianos que puedo usar para probar la diferencia entre la media de dos muestras.
Respuestas:
Esta es una buena pregunta, que parece aparecer mucho: enlace 1 , enlace 2 . El artículo Bayesian Estimation Superseeds the T-Test que Cam.Davidson.Pilon señaló es un excelente recurso sobre este tema. También es muy reciente, publicado en 2012, y creo que en parte se debe al interés actual en el área.
Intentaré resumir una explicación matemática de una alternativa bayesiana a la prueba t de dos muestras. Este resumen es similar al artículo BEST que evalúa la diferencia en dos muestras comparando la diferencia en sus distribuciones posteriores (explicadas más adelante en 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)
Para comparar las medias muestrales necesitamos estimar cuáles son. El método bayesiano para hacerlo utiliza el teorema de Bayes: P (A | B) = P (B | A) * P (A) / P (B) (la sintaxis de P (A | B) se lee como la probabilidad de A dado B)
Gracias a los métodos numéricos modernos, podemos ignorar la probabilidad de B, P (B) y usar el enunciado proporcional: P (A | B) P (B | A) * P (A) En vernáculo bayesiano, el posterior es proporcional a la probabilidad veces anterior
Aplicando la teoría de Bayes a nuestro problema en el que queremos conocer las medias de las muestras dados algunos datos obtenemos . El primer término a la derecha es la probabilidad, , que es la probabilidad de observar los datos de la muestra dada la media. El segundo término es el anterior, , que es simplemente la probabilidad de la media. Descubrir los antecedentes apropiados sigue siendo un poco un arte y es uno de los mayores críticos de los métodos bayesianos.
Pongámoslo en código. El código hace que todo sea mejor.
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)
}
Hice algunas suposiciones anteriores que deben justificarse. Para evitar que los previos perjudiquen la media estimada, quería hacerlos amplios y uniformes sobre valores plausibles con el objetivo de permitir que los datos produzcan las características del posterior. Usé la configuración recomendada de BEST y distribuí los mu normalmente con media = media (agrupada) y una desviación estándar amplia = 1000 * sd (agrupada). Las desviaciones estándar las puse en una distribución exponencial amplia, porque quería una distribución amplia sin límites.
Ahora podemos hacer el posterior
posterior <- function(parameters) {likelihood(parameters) * prior(parameters)}
Tomaremos muestras de la distribución posterior utilizando una cadena de Markov Monte Carlo (MCMC) con modificación de Metropolis Hastings. Es más fácil de entender con código.
#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 matriz de resultados es una lista de muestras de la distribución posterior para cada parámetro que podemos usar para responder a nuestra pregunta original: ¿Es sample.1 diferente de sample.2? Pero primero para evitar los efectos de los valores iniciales, "quemaremos" los primeros 500 valores de la cadena.
#burn-in
results <- results[500:n.iter,]
Ahora, ¿es sample.1 diferente de sample.2?
mu1 <- results[,1]
mu2 <- results[,3]
hist(mu1 - mu2)
mean(mu1 - mu2 < 0)
[1] 0.9953689
De este análisis concluiría que existe una probabilidad del 99.5% de que la media para la muestra.1 sea menor que la media para la muestra.2.
Una ventaja del enfoque bayesiano, como se señala en el artículo BEST, es que puede hacer teorías sólidas. Por ejemplo, ¿cuál es la probabilidad de que la muestra.2 sea 5 unidades más grande que la muestra?
mean(mu2 - mu1 > 5)
[1] 0.9321124
Llegaríamos a la conclusión de que existe una probabilidad del 93% de que la media de la muestra.2 sea 5 unidades mayor que la muestra.1. Un lector observador lo encontraría interesante porque sabemos que las poblaciones verdaderas tienen medias de 100 y 103 respectivamente. Esto probablemente se deba al pequeño tamaño de la muestra y a la elección de utilizar una distribución normal para la probabilidad.
Terminaré esta respuesta con una advertencia: este código tiene fines didácticos. Para un análisis real, use RJAGS y, según el tamaño de su muestra, ajuste una distribución t para la probabilidad. Si hay interés, publicaré una prueba t usando RJAGS.
EDITAR: según lo solicitado aquí es un modelo 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)
La excelente respuesta del usuario1068430 implementada en 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 análisis bayesiano, tiene más cosas para especificar (eso es realmente algo bueno, ya que brinda mucha más flexibilidad y capacidad para modelar lo que usted cree que es la verdad). ¿Está asumiendo valores normales para las probabilidades? ¿Tendrán los 2 grupos la misma varianza?
Un enfoque directo es modelar las 2 medias (y 1 o 2 variaciones / dispersiones) y luego mirar la parte posterior en la diferencia de las 2 medias y / o el intervalo creíble en la diferencia de las 2 medias.
Una explicación matemática de cuáles son algunos métodos bayesianos que puedo usar para probar la diferencia entre la media de dos muestras.
Hay varios enfoques para "probar" esto. Mencionaré una pareja:
Si desea una decisión explícita , puede consultar la teoría de la decisión.
Una cosa bastante simple que a veces se hace es encontrar un intervalo para la diferencia en las medias y considerar si incluye 0 o no. Eso implicaría comenzar con un modelo para las observaciones, los antecedentes de los parámetros y el cálculo de la distribución posterior de la diferencia en las medias condicionadas a los datos.
Debería decir cuál es su modelo (p. Ej., Varianza constante normal) y luego (al menos) un poco antes de la diferencia de medias y un previo de la varianza. Es posible que tenga prioridades en los parámetros de esas prioridades a su vez. O puede que no asuma una varianza constante. O puede suponer algo diferente a la normalidad.