나는 R에서 BEST와 같은 플러그 앤 플레이 방법을 찾고 있지 않지만 두 샘플의 평균 간의 차이를 테스트하는 데 사용할 수있는 베이지안 방법에 대한 수학적 설명을 찾고 있습니다.
나는 R에서 BEST와 같은 플러그 앤 플레이 방법을 찾고 있지 않지만 두 샘플의 평균 간의 차이를 테스트하는 데 사용할 수있는 베이지안 방법에 대한 수학적 설명을 찾고 있습니다.
답변:
이것은 좋은 질문입니다. 링크 1 , 링크 2 . 논문 Bayesian Estimation 은 Cam.Davidson.Pilon이 지적한 T- 테스트 를이 주제에 대한 훌륭한 자료로 대체합니다. 또한 2012 년에 출판 된 것은 최근에이 부분에 대한 현재의 관심 때문이라고 생각합니다.
두 샘플 t- 검정에 대한 베이지안 대안에 대한 수학적 설명을 요약하려고합니다. 이 요약은 사후 분포의 차이를 비교하여 두 표본의 차이를 평가하는 BEST 논문과 비슷합니다 (아래 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)
표본 평균을 비교하려면 표본이 무엇인지 추정해야합니다. 이를위한 베이지안 방법은 베이 즈 정리를 사용합니다 : P (A | B) = P (B | A) * P (A) / P (B) (P (A | B)의 구문은 확률로 읽습니다. 주어진 B)
현대의 수치 법 덕분에 우리는 B, P (B)의 확률을 무시하고 비례 통계를 사용할 수 있습니다. P (A | B) P (B | A) * P (A) 베이지안의 말초 는 비례합니다 가능성에 앞서
데이터가 주어지면 샘플의 평균을 알고 자하는 베이 즈 이론을 . 오른쪽의 첫 번째 항은 우도 , 평균이 주어진 표본 데이터를 관측 할 확률입니다. 두 번째 항은 이전의 이며 이는 단순히 평균 확률입니다. 적절한 선행을 알아내는 것은 여전히 약간의 기술이며 베이지안 방법의 가장 큰 비판 중 하나입니다.
코드에 넣자. 코드는 모든 것을 개선합니다.
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)
}
나는 이전에 정당화해야 할 몇 가지 가정을했다. 이전의 추정 된 평균을 편견에서 벗어나기 위해 데이터가 후자의 특징을 생성하게하기 위해 그 값을 그럴듯한 값보다 넓고 균일하게 만들고 싶었습니다. BEST의 권장 설정을 사용하고 mu = 평균 = 평균 (풀링) 및 넓은 표준 편차 = 1000 * sd (풀링)로 mu를 정상적으로 분배했습니다. 넓은 범위의 무제한 분포를 원했기 때문에 표준 편차를 넓은 지수 분포로 설정했습니다.
이제 우리는 후부를 만들 수 있습니다
posterior <- function(parameters) {likelihood(parameters) * prior(parameters)}
메트로폴리스 헤이스팅스 수정과 함께 마르코프 체인 몬테 카를로 (MCMC)를 사용하여 후방 분포를 샘플링합니다 . 코드를 이해하는 것이 가장 쉽습니다.
#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
}
결과 행렬은 원래의 질문에 답하는 데 사용할 수있는 각 모수에 대한 사후 분포의 표본 목록입니다. sample.1이 sample.2와 다른가요? 그러나 먼저 시작 값의 영향을 피하기 위해 체인의 처음 500 개 값을 "번인 (burn-in)"합니다.
#burn-in
results <- results[500:n.iter,]
이제 sample.1이 sample.2와 다른가요?
mu1 <- results[,1]
mu2 <- results[,3]
hist(mu1 - mu2)
mean(mu1 - mu2 < 0)
[1] 0.9953689
이 분석에서 나는 표본의 평균이 표본의 평균보다 작을 확률이 99.5 %라고 결론 내릴 것이다.
BEST 논문에서 지적했듯이 베이지안 접근법의 장점은 강력한 이론을 만들 수 있다는 것입니다. EG sample.2가 sample.1보다 5 단위 더 클 확률은 얼마입니까?
mean(mu2 - mu1 > 5)
[1] 0.9321124
표본의 평균이 표본보다 5 단위 더 클 확률이 93 %라고 결론을 내립니다 .1. 참관인은 우리가 참 모집단이 각각 100과 103의 평균을 가짐을 알고 있기 때문에 흥미로울 것입니다. 이것은 표본 크기가 작고 가능성에 정규 분포를 사용하는 선택 때문일 가능성이 큽니다.
이 답변을 경고와 함께 끝내겠습니다.이 코드는 교육용입니다. 실제 분석의 경우 RJAGS를 사용하고 표본 크기에 따라 가능성에 대한 t- 분포를 맞 춥니 다. 관심이 있다면 RJAGS를 사용하여 t-test를 게시 할 것입니다.
편집 : 여기에 요청 한대로 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)
Python으로 구현 된 user1068430의 탁월한 답변
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()
두 표본의 평균 차이를 테스트하기 위해 사용할 수있는 베이지안 방법에 대한 수학적 설명.
이것을 "테스트"하는 방법에는 여러 가지가 있습니다. 나는 몇 가지를 언급 할 것이다 :
명확한 결정 을 원한다면 결정 이론을 볼 수 있습니다.
때때로 수행되는 매우 간단한 일은 평균의 차이에 대한 간격을 찾아 0을 포함하는지 여부를 고려하는 것입니다. 그것은 데이터에 조건부 평균의 차이의 사후 분포의 매개 변수와 계산에 앞서 관측에 대한 모델로 시작하는 것을 포함합니다.
모형의 정의 (예 : 정규, 일정 분산)를 말한 다음 평균의 차이와 분산에 대한 사전 (적어도)을 말해야합니다. 그 이전의 매개 변수에 대한 우선 순위가 차례로있을 수 있습니다. 또는 일정한 분산을 가정 하지 않을 수 있습니다 . 아니면 정상 성 이외의 것을 가정 할 수도 있습니다.