Python 大都会黑斯廷斯接受拒绝执行

Python 大都会黑斯廷斯接受拒绝执行,python,montecarlo,markov-chains,mcmc,Python,Montecarlo,Markov Chains,Mcmc,我一直在读关于大都会黑斯廷斯(MH)算法的书。理论上,我理解算法的工作原理。现在,我正在尝试使用python实现MH算法 我遇到了以下情况。这正好适合我的问题,因为考虑到数据上的测量误差,我想用一条直线拟合数据。我将粘贴我发现难以理解的代码: # initial m, b m,b = 2, 0 # step sizes mstep, bstep = 0.1, 10. # how many steps? nsteps = 10000 chain = [] probs = [] naccept

我一直在读关于大都会黑斯廷斯(MH)算法的书。理论上,我理解算法的工作原理。现在,我正在尝试使用python实现MH算法

我遇到了以下情况。这正好适合我的问题,因为考虑到数据上的测量误差,我想用一条直线拟合数据。我将粘贴我发现难以理解的代码:

# initial m, b
m,b = 2, 0

# step sizes
mstep, bstep = 0.1, 10.

# how many steps?
nsteps = 10000

chain = []
probs = []
naccept = 0

print 'Running MH for', nsteps, 'steps'

# First point:
L_old    = straight_line_log_likelihood(x, y, sigmay, m, b)
p_old    = straight_line_log_prior(m, b)
prob_old = np.exp(L_old + p_old)

for i in range(nsteps):
    # step
    mnew = m + np.random.normal() * mstep
    bnew = b + np.random.normal() * bstep

    # evaluate probabilities
    # prob_new = straight_line_posterior(x, y, sigmay, mnew, bnew)

    L_new    = straight_line_log_likelihood(x, y, sigmay, mnew, bnew)
    p_new    = straight_line_log_prior(mnew, bnew)
    prob_new = np.exp(L_new + p_new)

    if (prob_new / prob_old > np.random.uniform()):
        # accept
        m = mnew
        b = bnew
        L_old = L_new
        p_old = p_new
        prob_old = prob_new
        naccept += 1
    else:
        # Stay where we are; m,b stay the same, and we append them
        # to the chain below.
        pass

    chain.append((b,m))
    probs.append((L_old,p_old))
print 'Acceptance fraction:', naccept/float(nsteps)
代码很简单,但是我很难理解MH是如何实现的


我的问题在
链中。追加
(从底部开始的第三行)。作者正在追加
m
b
是否接受或拒绝。为什么?他不应该只附加已接受的点吗?

快速阅读算法描述:当一个候选被拒绝时,它仍然算作一个步骤,但值与旧步骤相同。也就是说,
b,m
以任何一种方式追加,但它们仅在候选人被接受的情况下更新(到
bnew,mnew

以下R代码说明了捕获拒绝案例的重要性:

# 20 samples from 0 or 1. 1 has an 80% probability of being chosen.
the.population <- sample(c(0,1), 20, replace = TRUE, prob=c(0.2, 0.8))

# Create a new sample that only catches changes
the.sample <- c(the.population[1])

# Loop though the.population,
# but only copy the.population to the.sample if the value changes
for( i in 2:length(the.population))
{
  if(the.population[i] != the.population[i-1])
    the.sample <- append(the.sample, the.population[i])
}
该人群中出现1的概率为16/20或0.8。正是我们预期的概率

另一方面,仅记录更改的示例如下所示:

0 1 0 1 0 1
样本中出现1的概率为3/6或0.5


我们试图建立一个分布,拒绝新的价值观意味着旧的价值观比新的价值观更有可能。这需要被捕获,以便我们的分布是正确的。

是的,我理解这一点,我的问题是为什么?因为您仍然希望生成样本值。如果您未能附加任何内容,那么最终将得到一个包含少于
nsteps
个样本的链。
0 1 0 1 0 1