简体   繁体   English

我在 R 到 python 的翻译中做错了什么?

[英]What I am doing wrong in R to python translation?

I have a code in R which implements the Metropolis Hastings algorithm:我在 R 中有一个代码,它实现了 Metropolis Hastings 算法:

trials <- 100000
sim <- numeric(trials)
sim[1] <- 2
for (i in 2: trials) {
   old <- sim[i-1]
   prop <- runif(1,0,5)
   acc <- (exp(-(prop-1)^2/2) + exp(-(prop-4)^2/2)) /
     ( (exp(-(old-1)^2/2) + exp(-(old-4)^2/2)) )
   if (runif(1) < acc) 
     sim[i] <- prop
   else
     sim[i] <- old }
mean(sim)
var(sim)

and the results are right.结果是正确的。

But when I translate it in Python the results are different.但是当我在 Python 中翻译它时,结果就不同了。

trials = 100000
sim = np.repeat(0,trials+1)
sim[0] = 2
for i in range (2, trials):
    old = sim[i-1]
    prop = np.random.uniform(0,5,1)
    acc = (np.exp(-(prop-1)**2/2) + np.exp(-(prop-4)**2/2)) /( (np.exp(-(old-1)**2/2) + np.exp(-(old-4)**2/2)) )
    if np.random.uniform(1) < acc:
        sim[i] = prop
    else:
        sim[i] = old 

Why?为什么? What I am doing wrong here?我在这里做错了什么?

Firstly, you want to start your python for loop at i=1 in the range(1, trials) since Python starts at 0 .首先,由于 Python 从0开始,因此您希望在range(1, trials)中的i=1处启动 python for 循环。

Secondly, at if np.random.uniform(1) you are just producing 1.0 , so that needs to change, eg np.random.uniform(min, max, size=1) or np.random.uniform(size=1) if you just want a uniform number between 0 and 1. Have a look at the documentation for np.random.uniform if this isn't clear.其次, if np.random.uniform(1)你只是生产1.0 ,所以需要改变,例如np.random.uniform(min, max, size=1)np.random.uniform(size=1)如果您只想要一个介于 0 和 1 之间的统一数字。如果不清楚,请查看np.random.uniform文档

Update更新
Thirdly, you are unknowingly casting to integers, so this needs to be handled also.第三,你在不知不觉中转换为整数,所以这也需要处理。 When being used to R this is easy to forget (I just did myself).当习惯了 R 时,这很容易忘记(我只是自己做的)。 I have refactored your code below, and this solution should provide you with a similar result to what you see in R.我在下面重构了您的代码,该解决方案应该为您提供与您在 R 中看到的类似的结果。

Here I turned sim into a float vector, and I made sure to subtract and divide using floats inside the exp -functions.在这里,我将 sim 转换为float向量,并确保在exp函数中使用浮点数进行减法和除法。 Hope this works for you.希望这对你有用。

trials = 100000
sim = np.repeat(0,trials).astype(np.float64)
sim[0] = 2.0
for i in range (1, trials):
    old = sim[i-1]
    prop = np.random.uniform(0,5,1)
    acc = (np.exp(-(prop-1.0)**2/2.0) + np.exp(-(prop-4.0)**2/2.0)) \
    / ( (np.exp(-(old-1.0)**2/2.0) + np.exp(-(old-4.0)**2/2.0)) )
    if np.random.uniform(size=1) < acc:
        sim[i] = prop
    else:
        sim[i] = old 

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM