iTranslated by AI
Explanation and Python Implementation of the Metropolis-Hastings Algorithm
MCMC (Markov Chain Monte Carlo)
When you want to obtain samples from a certain distribution
MCMC (Markov Chain Monte Carlo) is a way to handle such cases. This is an algorithm that simulates a Markov chain that has
Metropolis Hastings Method
One of the methods to simulate a Markov chain that has
In the Metropolis Hastings method, the user needs to specify a proposal distribution. A "proposal" indicates where the next sample
As a simple example, let's say
In other words, the proposal distribution
Using this proposal distribution
- Set an appropriate initial value
X_1 = x_1 - Repeat the following for
a sufficient number of times:t \geq 1 - Sample a value
fromy (Proposal)Q(y|x_t) - Calculate
A = \min \left(1, \dfrac{\pi(y)Q(x_t|y)}{\pi(x_t)Q(y|x_t)} \right) - Accept the proposal with probability
and setA . Reject the proposal with probabilityx_{t+1} = y and remain at1-A x_{t+1} = x_t
- Sample a value
Implementation
As an example, suppose we want to obtain samples from the distribution:
Of course, for such a simple distribution, there is no need to go out of your way to use MCMC, but this is intended as a simple example.
The proposal distribution
The method where
Implementing this Metropolis method in Python looks like the following:
import numpy as np
def pi(x):
if x >= 0:
return np.exp(-x)
else:
return 0
xs = []
xs.append(10) # Set the initial value to 10 as an example
for i in range(10000):
y = np.random.normal(xs[i], 1) # Proposed value
a = min(1, pi(y) / pi(xs[i]))
u = np.random.rand() # Generate a uniform random number between 0 and 1
if u < a: # Accept
xs.append(y)
else: # Reject
xs.append(xs[i])
Now, the xs calculated this way can be considered samples of
import matplotlib.pyplot as plt
%matplotlib inline
plt.hist(xs, bins=20)
You can certainly see that it takes the form of a downward-sloping exponential distribution.
Also, let's compare the first 100 samples with the next 100 samples.
plt.hist(xs[0:100], bins=20)
plt.hist(xs[100:200], bins=20)
The latter seems to show the downward slope more clearly. You can see that by increasing the number of trials, it gets closer to a sample of
Discussion