The basics of Monte Carlo integration
By: Victor Cumer
Tags: Monte Carlo Method, Python, Numerical Integration, Data Science

Crude Monte Carlo method

The crude Monte Carlo method is the most basic application of the concept described above:

Random draws x_i are made over X following a uniform law.

We compute the sum of f(x_i), multiply it by (b-a) and divide by the number of samples N.

To illustrate the process, let’s take a concrete use case: we want to integrate the beta distribution function beta(x, 50, 50) over the interval [0 ; 0.55] as it is described on figure 3 below. If X is a random variable that follows this beta law, this integral corresponds to P(X <= 0.55), which can be calculated exactly with the cumulative density function (c.d.f.) of the beta(x, 50, 50) density law: it gives 0.8413. We will try to approach this number through Monte Carlo integration.

Beta distribution function to integrate

figure 3

Monte Carlo estimator

As describe earlier, we will do N = 10 000 random draws of x_i using the uniform distribution. Then, we compute the integral estimation and the associated error using the following formulas:

Crude Method with python

figure 4

The blue points correspond to the 10 000 values of f(x_i) computed from the uniform draws we made over X.

We can already notice that because the draws were made uniformly over X (i.e. the horizontal axe), we have quite some space and less overlapping between the points when the slope of the curve increases.

Geometric estimation of the area under the curve

Another way to compute the integral is to make a geometric approximation of the integral. Indeed, by using uniform random draws over both x and y axes, we map a 2D rectangle that correspond to the desired range [x_min ; x_max] and compute the ratio of points under the curve over the total points drawn in the rectangle. This ratio would converge to the area under the curve with N, the number of draws. This idea is illustrated in figure 5.

Geometric approximation with python

figure 5

Importance Sampling

The idea behind Importance Sampling is very simple: as the error of the Monte Carlo estimator is proportional to the standard deviation of f(x) divided by the square root of the number of samples, we should find a cleverer method to chose x_i than the uniform law. Importance Sampling is in fact a way to draw x_i to reduce the variance of f(x). Indeed, for the function beta(x, 50, 50) we noticed a lot of x_i over [0 ; 0.55] will give a f(x) ~ 0, while only few values of x around 0.5 will give f(x) ~ 8.

The key idea of Importance Sampling is that we use a probability density function (p.d.f.) to draw samples over X that will give more chance to high values of f(x) to be computed, and then we weight the sum of f(x) by the chance that x happened (i.e. the value of the p.d.f.).

Following this idea, the integral we try to approximate will became:

Integral value approximation with Importance Sampling

with:

N: number of samples

f: function to integrate

g: p.d.f. chosen for the random draws over X

G: the inverse function of g

And the variance of f used to compute error of the estimator becomes:

Variance of the estimator with Importance Sampling

Back to our use case with the beta(x,50,50) distribution function, it seems that using a normal distribution centered at 0.5 as the g function could help us. The links between f and g are shown on figure 6 below.

figure 6

Figure 7 below shows the results of using such a method to integrate beta(x,50,50) over [0 ; 0.55]. The density of the points also shows the relevance to use of the Gaussian p.d.f compared to the uniform law to choose x_i: the x_i points are concentrated in areas of interest, where f(x_i) != 0.

Importance Sampling with python

figure 7: Importance Sampling (left) vs Crude Integration (right)

Methods comparison

Here is the summary of integral values and relative errors. We reduce x4 the error with the Importance Sampling method.

Integrating 3D functions

Figure 8 takes an example of 3D jointplot mapped on a 2D space (x_A, x_B). This example is taken from the analysis of Bayesian A/B tests. The blue contour plot corresponds to beta distribution functions for 2 different variants (A and B). The idea is to compute the probability that variation B is better than variation A by calculating the integral of the joint posterior f, the blue contour plot on the graph, for x_A and x_B values that are over the orange line (i.e. values where x_B >= x_A ).

Joint probability density function to integrate

figure 8

Thus, let’s compute the integral that corresponds to the area below the blue 3D bell for values of x_A and x_B that respect x_B >= x_A (upper to the orange line on the graph). This time we will draw N = 100 000 samples.

With the crude method:

Integral value: 0.7256321849276118

Calculation error: 0.01600479134298051

With Importance Sampling

Integral value: 0.7119836088517515

Calculation error: 0.0018557917512560286

The importance sampling method enabled to reach an almost x10 more precise result with the same amount of samples.

Conclusion

The crude method and importance sampling belong to a large range of Monte Carlo integration methods. Here you have all the material to implement these two techniques in python with no more than usual libraries as numpy and scipy. Keep in mind that Monte Carlo integration is particularly useful for higher-dimensional integrals. With the example we came through, we got a x10 improvement regarding precision for the 3D case, while it was a x4 improvement for the 2D case.

References