Understanding Monte Carlo Methods from Scratch: Part 3 - Basic Operations for Handling Random Numbers in Python
Introduction
Last time, we learned the theory of random numbers and probability distributions.
In this installment, we will explain in detail how to freely handle random numbers using Python.
To implement the Monte Carlo method, it is essential to generate random numbers and create samples that follow a distribution.
Here, we will master basic operations using the standard library and NumPy, preparing for Monte Carlo integration and MCMC in future sessions.
Libraries for handling random numbers in Python
Python has the standard library 'random' for random number generation and 'numpy.random' for scientific computing.
'random' is simple and easy to use, while 'numpy' can efficiently generate large quantities of random numbers.
Since the Monte Carlo method requires a large number of samples, using NumPy is the standard approach.
Generating uniform random numbers
First, let's look at uniform random numbers. To generate uniform random numbers in the interval [0, 1], we use random.random().
import random
# 0から1の一様乱数を10個生成
uniform_randoms = [random.random() for _ in range(10)]
print("一様乱数:", uniform_randoms)If you want to specify an interval, use random.uniform(a, b).
# 区間 [5,10] の一様乱数を生成
uniform_randoms_range = [random.uniform(5, 10) for _ in range(10)]
print(uniform_randoms_range)It is even easier using NumPy.
import numpy as np
# 区間 [0,1] の一様乱数を100000個生成
samples = np.random.uniform(0, 1, 100000)
print("平均:", np.mean(samples))If you generate a large number of random numbers and check the statistics, the mean should be around 0.5 and the standard deviation should be approximately 0.288.
Random numbers from a normal distribution
The normal distribution is frequently used in the Monte Carlo method.
In Python, we use random.gauss(mu, sigma) or numpy.random.normal(mu, sigma, size).
# randomモジュールで正規分布乱数
normal_randoms = [random.gauss(0, 1) for _ in range(10)]
print("正規分布乱数:", normal_randoms)
# NumPyで大量の正規分布乱数
samples_normal = np.random.normal(0, 1, 100000)
print("平均:", np.mean(samples_normal))
print("標準偏差:", np.std(samples_normal))If you draw a histogram, you can confirm a bell-shaped distribution with a peak in the center.
Random numbers for dice and discrete distributions
As an example of a discrete distribution, we will simulate a die roll.
# サイコロの目(1〜6)を100回シミュレーション
dice_rolls = [random.randint(1, 6) for _ in range(100)]
print("サイコロの目:", dice_rolls[:20])In NumPy, you use np.random.randint(low, high, size).
import numpy as np
# high は排他なので 7 にする(1〜6)
np.random.seed(42)
dice = np.random.randint(1, 7, 100000)
print("平均:", dice.mean()) # 3.5 に近い値が得られるThe average should be approximately 3.5.
Random Number Reproducibility and Seeds
In Monte Carlo methods, we fix the random number seed to reproduce results.
random.seed(42)
print(random.random()) # 毎回同じ値
np.random.seed(42)
print(np.random.rand()) # 毎回同じ値By setting a seed, you can reproduce the same sequence of random numbers.
This is essential when conducting experiments or verification.
Practice: Checking Distributions with Histograms
Visualizing the distribution of random numbers deepens your understanding. Let's try drawing a histogram using NumPy and Matplotlib.
import matplotlib.pyplot as plt
# 正規分布の乱数を生成
samples = np.random.normal(0, 1, 100000)
# ヒストグラムを描画
plt.hist(samples, bins=50, density=True, alpha=0.6, color='g')
plt.title("正規分布のヒストグラム")
plt.show()Looking at this graph, you can confirm a shape close to the theoretical normal distribution.

Summary
In this session, we learned the basic operations for handling random numbers in Python.
I believe you have understood uniform random numbers, normal distribution random numbers, discrete distribution random numbers, and how to ensure reproducibility using seeds.
Next time, we will actually implement Monte Carlo integration using these random numbers and compare the results with theoretical values.
