Rand生成随机数的库

作者:禅与计算机程序设计艺术

1.简介

随着科技的进步和应用的广泛,越来越多的人都需要生成随机数。如今人工智能、机器学习、区块链等领域都在用到随机数来训练模型、测试算法、解决密码学问题、进行投票选举等方面。现代计算机系统中,CPU的运算能力越来越强,通过某种方式产生的随机数已经不能满足需求了,因此人们又逐渐寻找更加高效的随机数生成方法。
本文将介绍几个Python中非常流行的随机数生成库,并分析其实现原理。

2.概述

Python是一个很受欢迎的编程语言,它具有简单易用、灵活强大、可移植性强等特性,特别适合科学计算、数据分析等领域的工程实践。近几年来,Python在数据处理和科学计算领域有着极大的增长,它成为许多知名开源项目(如pandas、numpy、matplotlib等)的必备语言。与此同时,越来越多的科研工作者和企业也开始转向基于Python的机器学习和深度学习框架。同时,还有很多开发者开始关注并选择Python作为自己的主要语言。那么如何生成随机数呢?Python提供了几种很流行的随机数生成库,它们分别是:random, numpy.random, scipy.stats。本文首先对这些库进行简单的介绍,然后对每一个库的生成随机数原理进行分析,最后通过具体的示例代码,展示各种随机数库的应用。

3. Random模块

random模块是在Python标准库中内置的一个用于生成随机数的模块。该模块提供的方法可以用来生成均匀分布的随机浮点数、整数、长整数、0或1之间的随机布尔值。由于生成随机数的需求一直都是最基本的功能,所以Python的标准库中的random模块无疑是最基础也是最常用的随机数模块。

3.1 random模块

该模块提供了以下函数:

  1. randrange(start, stop[, step]): 返回一个从start (默认值为 0)开始的、步长为step (默认值为 1)的范围内的随机整数,包括start但不包括stop。例如,randrange(10) 可能返回 0 或 10,而 randrange(-10, 10) 可以返回 -10、-9、…、9 或 0,还可以指定步长,比如 randrange(-10, 10, 2) 只会返回 -10 和 0 的偶数。
  2. randint(a, b): 返回一个随机整数 N,其中 a <= N <= b。
  3. uniform(a, b): 返回一个随机浮点数 X,其中 a <= X <= b。
  4. choice(seq): 从非空序列 seq 中随机地选择一个元素。如果 seq 是空列表或元组,则引发 IndexError。
  5. shuffle(x[, random]): 将序列 x 中的元素随机排列。如果给定了一个可调用对象 random ,它应该是一个返回 [0.0, 1.0) 间的随机小数的函数。
  6. sample(population, k): 从非重复的 population 随机地选择 k 个元素组成一个新列表,并返回这个新列表。

3.2 numpy.random模块

NumPy(Numerical Python的缩写)是一个用于科学计算的Python库,提供了矩阵和矢量运算、线性代数、随机数生成等功能。NumPy模块提供了另一种生成随机数的方法——numpy.random模块。numpy.random模块中提供了多个函数用于生成随机数组、随机数、随机样本等。下面我们详细看一下numpy.random模块中各个函数的功能和使用方法。

3.2.1 numpy.random.rand()

rand() 方法创建一个包含[0,1)间的均匀分布的随机数数组。输入参数表示要生成的维度大小,例如若输入 (m, n), 则生成一个 (m,n) 维度的数组,每个元素的值都是 [0,1) 之间的均匀分布的随机数。例如:

import numpy as np
arr = np.random.rand(3, 2)   # 生成3x2维度的随机数组
print(arr)                   # [[0.57758346 0.9660965 ]
                       #  [0.1683679  0.96906748]
                       #  [0.63408429 0.1329728 ]]
3.2.2 numpy.random.randn()

randn() 方法创建符合正态分布 (mean=0, stddev=1) 的随机数数组。输入参数同样表示要生成的维度大小。例如:

import numpy as np
arr = np.random.randn(3, 2)    # 生成3x2维度的符合正态分布的随机数组
print(arr)                    # [[-0.30420374 -0.60714664]
                        #  [-0.04866647 -1.01930853]
                        #  [ 0.56016882  0.61841751]]
3.2.3 numpy.random.randint()

randint() 方法用于生成指定范围内的随机整数。第1个参数表示下限,第2个参数表示上限(不含),第3个参数表示要生成的维度大小。例如:

import numpy as np
arr = np.random.randint(1, 10, size=(3, 2))   # 生成3x2维度的介于1到9之间的随机整数数组
print(arr)                                    # [[5 7]
                                         #  [2 8]
                                         #  [3 6]]
3.2.4 numpy.random.permutation()

permutation() 方法用于生成一个序列的随机排列,返回重新排序后的序列。例如:

import numpy as np
arr = np.array([1, 2, 3])
permuted_arr = np.random.permutation(arr)      # 生成一个[1, 2, 3]序列的随机排列
print(permuted_arr)                            # [2 3 1]

此外,np.random 模块还提供了一些其他函数,比如 uniform() 函数用于生成均匀分布的随机数; normal() 函数用于生成符合正态分布的随机数; shuffle() 函数用于打乱一个序列; choice() 函数用于从一个序列或数组中随机地选择一个元素等。

3.3 scipy.stats模块

SciPy(Scientific Python的缩写)是一个开源的Python库,提供了许多用于科学计算和工程实践的工具包,其中包括线性代数、优化、统计和信号处理等。SciPy中有一个子模块 scipy.stats,专门用于统计学上的分布和统计指标。SciPy.stats模块提供了各种分布的密度函数、随机数生成器、统计检验、信息论等。
在利用 scipy.stats 模块时,通常会先定义一个分布实例,然后利用实例的相关方法来获取相关的信息和结果。下面我们就通过实例来了解一下 scipy.stats 模块的相关用法。

3.3.1 分布实例

使用 scipy.stats 模块之前,首先需要实例化一个分布对象。比如,创建一个均值为μ=0、方差为σ=1的正态分布对象,可以通过如下代码实现:

from scipy.stats import norm
dist = norm(loc=0, scale=1)

loc 参数表示期望值 μ;scale 参数表示标准差 σ。对于二项分布(binomial distribution)、泊松分布(poisson distribution)、负二项分布(negative binomial distribution)等其他分布,也可以类似的方式创建相应的分布对象。这里只讨论最常用的两种分布——正态分布和二项分布。

3.3.2 正态分布概率密度函数

有关正态分布概率密度函数(Probability Density Function,PDF),其定义如下:
f ( x ) = 1 σ 2 π exp ⁡ ( − ( x − μ ) 2 2 σ 2 ) f(x)=\frac{1}{\sigma \sqrt{2\pi}}\exp (-\frac{(x-\mu)^2}{2\sigma^2}) f(x)=σ2π 1exp(2σ2(xμ)2)
其中, μ \mu μ 为期望值(location), σ \sigma σ 为标准差(scale)。利用分布实例的方法 pdf(), 可以得到对应的概率密度函数。例如:

from scipy.stats import norm
dist = norm(loc=0, scale=1)     # 创建均值为0、标准差为1的正态分布对象
x = np.linspace(-5, 5, num=100) # 生成[-5,5]间的100个等间距的x轴坐标
pdfs = dist.pdf(x)              # 获取100个x轴坐标对应的概率密度值
plt.plot(x, pdfs)               # 折线图展示概率密度值
plt.show()                      # 显示图像

执行以上代码后,可以看到一个均值为0、标准差为1的正态分布的概率密度函数曲线。
在这里插入图片描述

3.3.3 二项分布概率质量函数

有关二项分布概率质量函数(Probability Mass Function,PMF),其定义如下:
P ( k ; n , h e t a ) = ( n k ) h e t a k ( 1 − h e t a ) ( n − k ) \mathrm{P}(k;n, heta)=\begin{pmatrix}n \\ k\end{pmatrix} heta^{k}(1- heta)^{(n-k)} P(k;n,heta)=(nk)hetak(1heta)(nk)
其中, n n n 表示抛掷次数; k k k 表示成功次数;$ heta$ 表示发生正面的概率。利用分布实例的方法 pmf(), 可以得到对应的概率质量函数。例如:

from scipy.stats import binom
dist = binom(n=10, p=0.5)       # 创建10次抛掷,发生正面概率为0.5的二项分布对象
ks = range(11)                  # 生成1到10之间的整数序列
pms = dist.pmf(ks)              # 获取ks各个值的概率质量值
plt.bar(ks, pms)                # 柱状图展示概率质量值
plt.show()                      # 显示图像

执行以上代码后,可以看到一个抛掷10次,发生正面概率为0.5的二项分布的概率质量函数曲线。
在这里插入图片描述

4.具体案例及源码解析

下面我们结合具体案例和源码解析,来具体阐述不同随机数生成库的优劣和使用方法。

4.1 背景介绍

在深度学习领域中,我们经常会遇到大量的数据和标签,这些数据往往是高维度的,很难直观地呈现出结构。因此,我们需要对这些数据进行降维或者从高维空间映射到低维空间,使得数据的可视化变得更容易。这一过程通常被称作数据降维,而对数据的降维通常需要用到随机数。
目前市面上主要有两种随机数生成库:Numpy中的Random模块和Scipy中的Stats模块。Random模块是一个生成随机数的库,它的函数包括 rand(), randn(), randint(), randn(), random(), uniform(), beta(), exponential(), binomial() 等。Scipy中的Stats模块提供了统计学相关的函数,包括用于统计学计算的函数,如总体方差var()、协方差cov()、卡方检验chisquare()等,以及用于概率分布的函数,如Normal()、Poisson()、Binomial()等。

  1. Numpy中的Random模块:
    NumPy(Numerical Python的缩写)是一个用于科学计算的Python库,提供了矩阵和矢量运算、线性代数、随机数生成等功能。Numpy模块提供了另一种生成随机数的方法——numpy.random模块。numpy.random模块中提供了多个函数用于生成随机数组、随机数、随机样本等。
    1.1. Random
    rand() 方法创建一个包含[0,1)间的均匀分布的随机数数组。输入参数表示要生成的维度大小,例如若输入 (m, n), 则生成一个 (m,n) 维度的数组,每个元素的值都是 [0,1) 之间的均匀分布的随机数。例如:
import numpy as np

arr = np.random.rand(3, 2)   # 生成3x2维度的随机数组
print(arr)                   # [[0.57758346 0.9660965 ]
                            #  [0.1683679  0.96906748]
                            #  [0.63408429 0.1329728 ]]

1.2. Randn
randn() 方法创建符合正态分布 (mean=0, stddev=1) 的随机数数组。输入参数同样表示要生成的维度大小。例如:

import numpy as np

arr = np.random.randn(3, 2)    # 生成3x2维度的符合正态分布的随机数组
print(arr)                    # [[-0.30420374 -0.60714664]
                             #  [-0.04866647 -1.01930853]
                             #  [ 0.56016882  0.61841751]]

1.3. Randint
randint() 方法用于生成指定范围内的随机整数。第1个参数表示下限,第2个参数表示上限(不含),第3个参数表示要生成的维度大小。例如:

import numpy as np

arr = np.random.randint(1, 10, size=(3, 2))   # 生成3x2维度的介于1到9之间的随机整数数组
print(arr)                                    # [[5 7]
                                                #  [2 8]
                                                #  [3 6]]

1.4. Permutation
permutation() 方法用于生成一个序列的随机排列,返回重新排序后的序列。例如:

import numpy as np

arr = np.array([1, 2, 3])
permuted_arr = np.random.permutation(arr)      # 生成一个[1, 2, 3]序列的随机排列
print(permuted_arr)                            # [2 3 1]
  1. Scipy中的Stats模块:
    SciPy(Scientific Python的缩写)是一个开源的Python库,提供了许多用于科学计算和工程实践的工具包,其中包括线性代数、优化、统计和信号处理等。SciPy中有一个子模块 scipy.stats,专门用于统计学上的分布和统计指标。SciPy.stats模块提供了各种分布的密度函数、随机数生成器、统计检验、信息论等。
    2.1. 正态分布
    当我们对样本进行统计分析时,我们通常假设数据服从正态分布。正态分布是一种特殊的概率分布,它代表着大部分数据分布,即数据中心是平均值,两侧离散程度均匀分布。
from scipy.stats import norm

mu, sigma = 0, 1            # 期望值和标准差
s = norm.rvs(size=1000, loc=mu, scale=sigma)  # 1000个样本
plt.hist(s, bins=50, normed=True)           # 以直方图形式展示样本分布
plt.xlabel('Value')                         # 设置x轴标签
plt.ylabel('Frequency')                     # 设置y轴标签
plt.title(r'Normal Distribution: $\mu=$%.2f,$\sigma=$%.2f'%(mu,sigma))        # 设置标题
plt.grid(True)                               # 添加网格
plt.show()                                   # 显示图像

2.2. 二项分布
二项分布是两类相互独立事件发生的次数的连续概率分布。典型的应用场景是二项试验,比如抛硬币n次,其中正面朝上的次数叫做“成功次数”,n叫做“试验次数”。二项分布可以用来表示二分类问题,如指纹识别、生物检测、营销推广等。

from scipy.stats import binom

n,p = 10, 0.5                 # 正面朝上的概率为0.5的二项试验,n=10次试验
s = binom.rvs(n, p, size=1000) # 1000个样本
plt.hist(s, bins=max(s), normed=True)             # 以直方图形式展示样本分布
plt.xlabel('Value')                             # 设置x轴标签
plt.ylabel('Frequency')                         # 设置y轴标签
plt.title(r'$B(%i,%.2f)$'%(n,p))                   # 设置标题
plt.grid(True)                                   # 添加网格
plt.show()                                       # 显示图像

猜你喜欢

转载自blog.csdn.net/universsky2015/article/details/132033807