分享

如何使用NumPy生成正态分布随机数

 基算仿真 2023-05-30 发布于江苏

概率分布描述了事件或实验所有可能结果的可能性。正态分布是最有用的概率分布之一,因为它可以很好地模拟许多自然现象。


正态分布

正态分布在其峰值周围是对称的。由于这种对称性,分布的均值通常用μ表示,并位于该峰值处。标准差σ描述了分布的扩散程度。

如果一些样本服从正态分布,则随机抽取一个样本接近均值的概率很高。实际上,大约68%的所有样本都在距离平均值一个标准差之内。

图中曲线下的面积解释为概率测量。绿色区域代表所有小于平均数一个标准偏差的样本,占曲线下面积的68%。

我们都知道在Matlab中可以使用randn函数创建正态分布的随机数。

在Python中,可以使用NumPy从正态分布中创建随机数样本。

numpy生成随机数

NumPy包含一个完整的子包numpy.random,专门用于处理随机数。由于历史原因,该软件包包括许多函数。

通常应该通过实例化默认随机数生成器(RNG)来开始:

import numpy as np
rng = np.random.default_rng()

RNG可以从许多不同的分布中生成随机数。

要从正态分布中抽样,可以使用.normal()函数:

虽然上图这些数字看起来是随机的,但很难确认这些数字是否从给定分布中抽取的。

因此,可以一次生成大量随机数:

numbers = rng.normal(size=10000)
numbers.mean()
numbers.std()

上述操作生成了一万个按照正态分布的数字。
若没有指定任何其他参数,则NumPy将创建所谓的标准正态分布数字,其以μ = 0为中心,并具有标准偏差σ=1。
可以使用mean检查平均值是否大约为零,使用.std()来检查标准偏差是否接近于1。
可以使用size指定随机数组的维度


绘制正态分布图像

这里尝试生成直方图表示上一节生成的10000个随机数

import matplotlib.pyplot as plt
plt.hist(numbers)
plt.show

直方图的纵轴表示不同区间的样本数量。

直方图的形状显示了与正态分布相关联的特征,它是对称的,具有一个明确定义的峰值,并向两侧逐渐变窄。

通过增加区间数量,可以得到更加平滑的图像

plt.hist(numbers,bins=500)
plt.show

SciPy库包含多个名为pdf()的函数。
这些是概率密度函数,可以使用它们来绘制理论概率分布,并与之前生成的随机数分布进行对比,可以看到生成的随机数符合正态分布

import scipy.stats
bins = 500
bin_width = (numbers.max() - numbers.min()) / bins
hist_area = len(numbers) * bin_width
x = np.linspace(numbers.min(), numbers.max(), 101)
plt.plot(x, scipy.stats.norm.pdf(x) * hist_area)
plt.hist(numbers,bins=500)
plt.show()

控制随机数生成器

自然界很多事物都服从正态分布,例如身高、体重、鞋码。

在像计算机这样的确定性系统中创建随机数并不容易。大多数随机数生成器不能产生真正的随机性,而是通过一种确定性和可重复的过程生成数字,使得这些数字看起来是随机的。

通常情况下,一个随机数生成器——或者更准确地说,伪随机数生成器(PRNG)——是从已知种子开始,并从中生成一个伪随机数。这样一个发生器的优点之一就在于可以再现那些伪造出来的数字:

如果使用特定的种子创建随机数生成器,则可以通过使用相同的种子稍后重新创建相同的随机数。在此示例中,对.normal()的第二次调用生成与第一次调用相同的数字。另一方面,如果您使用不同的种子初始化生成器,则会获得不同的随机数。

历史上,在NumPy中处理随机数时没有使用显式随机数生成器。而是直接调用诸如np.random.normal()之类的函数。但是,NumPy 1.17引入了显式随机数生成器,并鼓励尽可能多地使用这种新方法来处理随机数。

用中心极限定理逐步接近正常分布

正态分布在统计学和概率论中扮演着重要角色。它出现在许多实际例子和许多理论结果中。中心极限定理可以解释一些根本原因。

该结果表明,重复实验的平均值将近似于正态分布。这个成立的一个重要条件是实验具有相同的分布,尽管它们不需要是正态分布。

举个掷骰子的例子。普通骰子有六个面,在单次掷骰子时,每种结果——1、2、3、4、5或6都是等可能发生的。因此这些投掷是均匀分布的,然而,反复投掷骰子得到的平均数仍会接近正态分布。

可以使用NumPy来证明这一点。首先生成随机骰子投掷:

import numpy as np
import matplotlib.pyplot as plt
rng = np.random.default_rng(seed=2310)
rng.integers(low=1, high=6, endpoint=True, size=1)

使用 .integers() 并指定要在 1 到 6 的范围内(包括边界)抽样整数。接下来可以使用 size 来模拟重复掷骰子的分布。首先将掷骰子的次数重复两次,为了获得代表性分布,进行10000次这样的重复投掷,使用 .mean() 来计算两次掷骰子的平均值,然后绘制直方图来查看分布:

rolls = rng.integers(low=1, high=6, endpoint=True, size=(10_000, 2))
plt.hist(rolls.mean(axis=1), bins=21)
plt.show()

分布接近对称且有明显的峰值,该分布并不均匀,每个结果出现的可能性也不相等。

如果你增加重复的次数,那么你会发现分布会越来越接近正态分布。

这说明了中心极限定理:重复实验产生正态性。因为许多自然过程包括累加效应,它们通常会符合正态分布。

—— end ——

    转藏 分享 献花(0

    0条评论

    发表

    请遵守用户 评论公约

    类似文章 更多