如何使用 NumPy 获取正态分布的随机数

2023-12-02

概率分布描述了事件或实验所有可能结果的可能性。这正态分布是最有用的概率分布之一,因为它很好地模拟了许多自然现象。使用 NumPy,您可以根据正态分布创建随机数样本。

这种分布也称为高斯分布或者简单地钟形曲线。后者暗示了绘制分布时的形状:

The normal distribution: 68% of all samples lie within one standard deviation of the mean

正态分布围绕其峰值对称。由于这种对称性,分布的平均值通常表示为μ,正处于那个峰值。标准差,σ,描述了分布的分散程度。

如果某些样本呈正态分布,则随机样本的值很可能接近平均值。实际上,约 68%所有样本的平均值均在一个标准差之内。

您可以将图中曲线下的面积解释为概率的度量。深色区域代表与平均值小于 1 个标准差的所有样本,占曲线下全部面积的 68%。

在本教程中,您将学习如何使用 Python数值模拟处理正态分布的库,特别是如何创建正态分布的随机数。在此过程中,您将了解 NumPy随机数生成器 (RNG)以及如何确保您可以以可重复的方式处理随机性。

您还将了解如何使用以下方法可视化概率分布Matplotlib直方图,以及操纵平均值和标准差的效果。这中心极限定理解释了正态分布的重要性。它描述了任何重复实验或测量的平均值如何近似正态分布。

正如您将了解到的,您可以使用正确的 Python 代码进行一些强大的统计分析。要获取本教程的代码,请单击下面的链接:

免费奖金: 单击此处下载免费示例代码您将使用它在 NumPy 中根据正态分布生成随机数。

要继续操作,您需要安装一些软件包。首先,创建并激活虚拟环境。然后运行以下命令pip命令:

$ python -m pip install numpy matplotlib scipy

除了获取 NumPy 之外,您还安装了 Matplotlib 和 SciPy,因此您可以开始使用了。

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

NumPy 包含一个完整的子包,numpy.随机数,致力于与随机数。由于历史原因,这个包包含了很多功能。但是,您通常应该从实例化默认随机数生成器 (RNG) 开始:

>>>
>>> import numpy as np
>>> rng = np.random.default_rng()
>>> rng
Generator(PCG64) at 0x7F00828DD8C0

RNG 可以从许多不同的分布中生成随机数。要从正态分布中采样,您将使用.normal():

>>>
>>> rng.normal()
0.7630063999485851

>>> rng.normal()
0.46664545470659285

>>> rng.normal()
0.18800887515990947

虽然这些数字看起来是随机的,不管什么意思,很难确认一个或几个数字是从给定的分布中抽取的。您可以要求 NumPy 一次绘制多个数字:

>>>
>>> numbers = rng.normal(size=10_000)

>>> numbers.mean()
0.004567244040854705

>>> numbers.std()
1.0058207076330512

在这里,您生成一万个正态分布数字。如果您不指定任何其他参数,那么 NumPy 将创建所谓的标准正态分布数那些以μ= 0 并且有标准差σ= 1. 您确认您的数字的平均值大约为零。您还使用.std()检查标准差是否接近于 1。

NumPy 可以处理多维数字数组。您可以指定size用一个元组创造N维数组:

>>>
>>> rng.normal(size=(2, 4))
array([[ 0.44284801, -0.5197292 ,  0.36472606, -0.21618958],
       [-0.45235572,  0.04395177, -0.09295108, -0.70332948]])

在本例中,您创建了一个包含两行和四列的正态分布随机数的二维数组。如果您正在对重复实验进行建模,那么在多个维度上组织随机数据可能会很有用。你会看到一个实际的例子之后.

绘制正态分布数字

当您进行建模时,查看单一结果通常并不那么有趣。相反,您想要查看许多样本并尝试了解它们的分布。对于此类概述,通过绘制数字直方图来可视化分布非常有效。

对于第一个示例,请使用您在上面创建的数字:

>>>
>>> import numpy as np
>>> rng = np.random.default_rng()
>>> numbers = rng.normal(size=10_000)

您可以在直方图中绘制一万个数字:

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

跑步plt.show()将在单独的窗口中显示直方图。它看起来像这样:

Histogram of normally distributed random numbers

在直方图中,您的值以所谓的方式分组在一起垃圾箱。在上面,您可以数一下蓝色条,看看直方图有 10 个箱。请注意,最外面的条形很小并且很难发现。

直方图的垂直轴显示有多少样本落入每个箱中。直方图的形状显示了与正态分布相关的一些特征。它是对称的,有一个明确定义的峰,并向两侧逐渐变细。

根据数据集中的样本数量,您可能需要增加可视化中的箱数。您可以通过指定来做到这一点bins:

>>>
>>> plt.hist(numbers, bins=100)
>>> plt.show()

通过将 bin 数量增加到 100,您将获得更平滑的直方图:

Histogram of normally distributed random numbers

您选择的箱数可能会稍微改变直方图的外观,因此您在探索数据时应该尝试一些不同的选择。

请注意,当您有更多的垃圾箱时,每个垃圾箱中的值就会更少。这意味着您的绝对数字y-axis 很少有趣。它们将根据观察数量和箱数进行扩展。例如,您可以看到第一个图中的计数大约比第二个图中的计数高十倍,而第二个图中您使用的垃圾箱数量是第二个图中的十倍。

您可以通过将观测值数量乘以箱的宽度来计算直方图的面积。单个 bin 的宽度取决于最小值和最大值观察值和箱数。对于包含 100 个 bin 的直方图,您将得到以下结果:

>>>
>>> bins = 100
>>> bin_width = (numbers.max() - numbers.min()) / bins
>>> hist_area = len(numbers) * bin_width
>>> hist_area
763.8533882079863

同样,这个值本身通常并不是很有趣。但是,如果您想将直方图与理论正态分布进行比较,它可能会很有用。

SciPy 库包含几个名为pdf()。这些都是概率密度函数。您可以使用它们来绘制理论概率分布:

>>>
>>> import scipy.stats
>>> x = np.linspace(-4, 4, 101)
>>> plt.plot(x, scipy.stats.norm.pdf(x))
>>> plt.show()

在这里,你使用scipy.stats.norm.pdf()计算值的正态分布x介于 -4 和 4 之间。这将创建以下绘图:

The probability density function of the normal distribution

您可以识别具有单个峰值的对称曲线。根据定义,概率密度函数曲线下的面积为一。因此,如果您想将观测值直方图与理论曲线进行比较,那么您需要对后者进行缩放:

>>>
>>> x = np.linspace(numbers.min(), numbers.max(), 101)
>>> plt.hist(numbers, bins=100)
>>> plt.plot(x, scipy.stats.norm.pdf(x) * hist_area)
>>> plt.show()

在这里,您可以通过之前计算的直方图面积来缩放概率密度函数。生成的图显示了叠加在直方图顶部的正态分布:

The probability density function of the normal distribution on top of a histogram of samples

通过目视检查,您可以看到随机数据很好地遵循正态分布。

到目前为止,您已经了解了如何在 NumPy 中使用正态分布。在接下来的部分中,您将详细了解正态分布如何以及为何有用。

指定平均值和标准差

很多例子自然发生的正态分布数据,包括出生体重、成年身高和鞋码。假设您想要为一台包装小麦袋的机器建模。通过观察和测量,你知道每袋小麦的重量呈正态分布,平均值为μ= 1023 克,标准偏差为σ= 19 克。

之前,您已经看到过以μ= 0。但是,您可以用任何均值定义正态分布,μ,以及任何正标准差,σ。在 NumPy 中,您可以通过指定两个参数来完成此操作:

>>>
>>> import numpy as np
>>> rng = np.random.default_rng()
>>> weights = rng.normal(1023, 19, size=5_000)
>>> weights[:3]
array([1037.4971216 , 1031.86626364, 1026.57216863])

与之前相比,现在您的随机值大多略高于 1000。您可以计算观测值的平均值和标准差:

>>>
>>> weights.mean()
1023.3071473510166

>>> weights.std()
19.25233332725017

同样,随机数的特征与其理论值接近,但并不完全相等。您可以绘制数据:

>>>
>>> import matplotlib.pyplot as plt
>>> plt.hist(weights, bins=50)
>>> plt.show()

这些命令生成如下图:

Histogram of the distribution of wheat bag weights

当您认识到直方图的形状时,请注意x- 轴发生移动,以便大多数值都高于 1000。实际上,您可以使用 NumPy 来计算低于 1000 克的观测值的比率:

>>>
>>> np.mean(weights < 1000)
0.117

NumPy 计算布尔表达式,例如weights < 1000元素方面。结果是一个数组TrueFalse值取决于每袋小麦的重量。因为TrueFalse可以解释为10,分别可以使用mean()计算比率True价值观。

在上面的示例中,您会看到 11.7% 的袋子的测量重量小于 1000 克。您还可以通过查看绘图来估计类似的数字。左边曲线下的面积x=1000代表较轻的麦袋。

您已经看到可以生成具有给定平均值和标准差的正态数字。在下一节中,您将更仔细地了解 NumPy 的随机数生成器。

在 NumPy 中使用随机数

在计算机等确定性系统中创建随机数并非易事。大多数随机数生成器不会产生真正的随机性。相反,它们通过确定性和可再现的过程生成数字,使数字看起来是随机的。

一般来说,随机数生成器(或更准确地说,伪随机数生成器 (PRNG))是一种从已知的种子并从中生成一个伪随机数。这种生成器的优点之一是您可以重现随机数:

>>>
>>> import numpy as np

>>> rng = np.random.default_rng(seed=2310)
>>> rng.normal(size=3)
array([0.7630064 , 0.46664545, 0.18800888])

>>> rng = np.random.default_rng(seed=2310)
>>> rng.normal(size=3)
array([0.7630064 , 0.46664545, 0.18800888])

>>> rng = np.random.default_rng(seed=2801)
>>> rng.normal(size=3)
array([-1.90550297,  0.05608914, -0.29362926])

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

从历史上看,在 NumPy 中处理随机数时,您没有使用显式随机数生成器。相反,您调用了类似的函数np.random.normal()直接地。然而,numpy 1.17引入了显式随机数生成器,我们鼓励您尽可能使用这种处理随机数的新方法。

新机制的优点之一是更加透明。如果您的程序中的不同位置需要随机数,那么您应该传递随机数生成器。您可以了解有关 NumPy 随机数策略的更多信息新经济政策19,NumPy 增强提案之一。

在最后一部分中,您将返回正态分布并了解更多关于它为何如此普遍的信息。

用中心极限定理迭代至正态性

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

结果表示重复实验的平均值将近似正态分布。实现这一点的一个重要标准是实验具有相同的分布,尽管它们不需要呈正态分布。

举个实际的例子,考虑掷骰子。普通骰子有六个面,在掷骰子时,每种结果(1、2、3、4、5 或 6)的可能性均等。因此,这些卷是均匀分布。然而,重复掷骰子的平均值仍接近正态分布。

您可以使用 NumPy 来演示这一点。首先,生成随机骰子:

>>>
>>> import numpy as np
>>> rng = np.random.default_rng(seed=2310)
>>> rng.integers(low=1, high=6, endpoint=True, size=1)
array([6])

你用.integers()并指定您想要对 1 到 6 范围内的整数进行采样(包含 1 和 6)。接下来,您可以使用size模拟重复骰子的分布。首先重复掷骰子两次。为了获得代表性分布,您需要执行一万次这样的重复滚动:

>>>
>>> rolls = rng.integers(low=1, high=6, endpoint=True, size=(10_000, 2))

您可以使用.mean()计算两次滚动的平均值,然后绘制直方图以查看分布:

>>>
>>> import matplotlib.pyplot as plt
>>> plt.hist(rolls.mean(axis=1), bins=21)
>>> plt.show()

这将产生以下情节:

Histogram of the distribution of the average of two dice rolls

虽然分布接近对称并且具有明显的峰值,但您会注意到形状更像三角形而不是钟形。与此同时,分布不再表现出均匀性,即每种结果的可能性均等。

接下来,尝试用十次重复的骰子进行相同的操作:

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

现在,分布更加接近熟悉的形状:

Histogram of the distribution of the average of ten dice rolls

如果增加重复掷骰的次数,您会发现分布将越来越接近正态分布。这说明了中心极限定理:重复实验产生正态性。由于许多自然过程都包含加性效应,因此它们通常很好地遵循正态分布。

结论

在本教程中,您学习了如何在 NumPy 中处理正态分布数据,以及如何在 Matplotlib 中绘制它们。正态分布是最常见的概率分布之一,您已经了解了如何直观地将样本数据的分布与理论正态分布进行比较。

中心极限定理解释了为什么正态分布随处可见的原因之一。重复实验的平均值趋于正态性。

您有正态分布数字的有趣示例吗?在下面的评论中与社区分享。

免费奖金: 单击此处下载免费示例代码您将使用它在 NumPy 中根据正态分布生成随机数。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

如何使用 NumPy 获取正态分布的随机数 的相关文章

随机推荐

  • 通过在tableview iPhone中选择tableview行添加动态子行错误?

    我想动态添加行 我有建筑物名称的表格视图列表 如果有人选择建筑物 didSelectRowAtIndexPath 则建筑物的相应楼层应动态添加为子行 这就像最大化和最小化相应建筑列表选择上的子行一样 我该怎么做呢 提前致谢 NSIntege
  • Vue.js 3 - 在 vue 中使用 Vue I18n 插件时出错 - 无法设置未定义的属性“_vm”

    我刚刚开始使用 Vue js 并通过一些在线代码片段和教程来学习它 我正在尝试为我的 vue 项目实现国际化支持 但我在网络控制台中遇到错误 这是我的代码片段 main js import createApp from vue import
  • tkinter 图标可以使用哪些文件格式?

    我知道这可能很明显 但在 tkinter 中你可以设置一个图标 但我发现很难找到一个图标 我只是想知道你是否必须使用 ico文件的格式或者是否有办法使用 png or jpeg files 目前我有 window Tkinter Tk wi
  • 处置 Angular 2 应用程序或组件

    有没有办法处理 angular2 应用程序或组件 我正在做一个混合的 ASP NET MVC 和 Angular 2 应用程序 其中 ASP NET MVC 加载部分视图 包括 Angular 2 应用程序 现在 我需要为每个部分视图提供一
  • 基础 SDK 3.0 到 SDK 4.0

    我安装了 SDK 4 0 发现无法访问 3 2 之前的所有 SDK 版本 我找到了下载 SDK 3 1 3 的链接 因此我有两个 dmg 安装文件 问题 SDK 4 0 不允许访问早期版本吗 如果上面的答案是否定的 那么这是否意味着我必须安
  • 如何使用实体框架在连接表中插入数据?

    我是实体框架的新手 我希望获得一些帮助来在 连接表 中插入数据 我有三张桌子 Profiles Tags和一个叫ProfilesTags连接这两个表 类是从数据库 DB First 自动生成的 public partial class Pr
  • jQuery 函数声明说明

    我已经打开 jQuery 1 7 1 库并想研究代码 但我发现函数以奇怪的方式声明 对我来说 例如 show function some code here 我学会了这样定义函数 function show some code here 有
  • 如何使用 Happy 获得漂亮的语法错误消息?

    我目前正在使用快乐的解析器生成器 其他解析器生成器可以给出不错的消息 例如 意外的结束行 预期的 然后 很高兴我只得到当前的令牌和错误的位置 您能给我一个如何获取上述错误消息的示例吗 我为此目的编写了一个 Happy 功能 请参阅我的博文
  • SessionNotCreatedException:消息:会话未创建:此版本的 ChromeDriver 仅支持带有 Selenium ChromeDriver 的 Chrome 版本 76

    我目前使用的是 Chrome 75 并且我已经下载了兼容 Chrome 驱动程序对于Linux 我还将它添加到 PATH 变量中 但是 当我尝试使用以下命令初始化驱动程序时driver webdriver Chrome 我收到以下错误 se
  • Python eval():动态计算表达式

    目录 Understanding Python s eval 第一个参数 表达式 第二个参数 全局变量 第三种说法 本地人 Evaluating Expressions With Python s eval 布尔表达式 数学表达式 通用表达
  • 养成习惯

    学习 Python 编程等复杂技能是很困难的 根据我的经验 提高技能的追求永远不会停止 成功的最好方法是养成每天或每周的习惯努力提高你的技能 在本视频中 您将看到一些有关 Real Python 如何帮助您实现这一目标的提示 恭喜 该视频也
  • 该做什么和不该做什么:Python 编程建议

    本课程涵盖 PEP8 提供的更多建议 以保持一致性并消除歧义 在本课程结束时 您将知道如何检查 如果一个布尔值是True或者False 列表是否为空 变量是否具有定义的值 该参数不是 None 列表中的后缀和前缀
  • 如何设置 Django 项目

    当您开始构建任何新的 Django Web 应用程序时 您需要首先解决一个基本设置 本课程概述了设置 Django 项目的必要步骤 在本课程中 您将重点关注启动新的 Web 应用程序所需执行的初始步骤 您应该首先安装Python 并且应该知
  • 后续步骤:创建博客

    在本课程中 您构建了 Django 组合 了解了很多有关 Django 功能的知识 并与很多错误消息交了朋友 如果您想继续构建这个项目 您可以查看本课程基于的文章添加一个博客到您的网站 博客是与世界分享您的技术知识和写作技巧的好方法 下载
  • 了解 Python 模拟对象库

    目录 什么是模拟 Python 模拟库 The Mock Object 惰性属性和方法 断言和检查 管理模拟的返回值 管理模拟的副作用 配置你的模拟 patch patch 作为装饰器 patch 作为上下文管理器 修补对象的属性 在哪里打
  • Python heapq 模块:使用堆和优先级队列

    目录 What Are Heaps 数据结构 堆和优先级队列 堆的实现 优先级队列的用途 Heaps as Lists in the Python heapq Module 基本操作 高级别操作 堆可以解决的问题 如何发现问题 Exampl
  • PyQt 布局:创建具有专业外观的 GUI 应用程序

    目录 在 GUI 上布置图形元素 储备 PyQt 布局库 Using General Purpose Layout Managers 构建水平布局 QHBoxLayout 构建垂直布局 QVBoxLayout 在网格中排列小部件 QGrid
  • Python Turtle 初学者(概述)

    在本分步课程中 您将借助一个名为turtle的简单交互式Python库来学习Python编程的基础知识 如果您是 Python 初学者 那么本课程肯定会在您迈入编程世界的第一步时为您提供帮助 蟒蛇turtle库具有类似的交互功能 可以让新程
  • 创建一个千篇一律的 Django 应用程序

    有关本课程中使用的工具的更多信息 请查看 GNU纳米 django environ 的文档
  • 如何使用 NumPy 获取正态分布的随机数

    目录 如何使用 NumPy 生成正态分布的随机数 绘制正态分布数字 指定平均值和标准差 在 NumPy 中使用随机数 用中心极限定理迭代至正态性 结论 概率分布描述了事件或实验所有可能结果的可能性 这正态分布是最有用的概率分布之一 因为它很