随机抽样
import numpy as np # numpy version 1.18.5
import matplotlib.pyplot as plt
from scipy import stats
np.random.seed()
# 未设置seed,则每次产生的随机向量不同
for i in range(5):
print(np.random.permutation(8)) # 产生一个0-7的随机向量
[7 2 4 1 0 5 6 3]
[5 1 4 2 0 3 6 7]
[2 6 7 3 0 5 1 4]
[0 7 6 5 2 4 1 3]
[4 3 0 7 5 6 1 2]
# 设置seed之后,每次产生的随机向量都相同
for i in range(5):
np.random.seed(5)
print(np.random.permutation(8))
[7 2 4 1 0 5 6 3]
[7 2 4 1 0 5 6 3]
[7 2 4 1 0 5 6 3]
[7 2 4 1 0 5 6 3]
[7 2 4 1 0 5 6 3]
# seed需要在每次产生随机变量之前重新设置,否则重置为np.random.seed()
for i in range(5):
if i==0 or i==1:
np.random.seed(5)
print(np.random.permutation(10))
[9 5 2 4 7 1 0 8 6 3]
[9 5 2 4 7 1 0 8 6 3]
[2 5 6 3 8 1 4 7 9 0]
[0 3 7 8 9 2 5 6 4 1]
[8 4 3 6 7 5 0 2 1 9]
离散型随机变量
二项分布
在n次独立重复的伯努利试验中,设每次试验中事件A发生的概率为p。用X表示n重伯努利试验中事件A发生的次数,则X的可能取值为0,1,…,n,且对每一个k(0≤k≤n),事件{X=k}即为“n次试验中事件A恰好发生k次”,随机变量X的离散概率分布即为二项分布(Binomial Distribution)公式为:
P
{
X
=
k
}
=
(
k
n
)
p
k
(
1
−
p
)
n
−
k
P\{X=k\}=(_k^n)p^k(1-p)^{n-k}
P{X=k}=(kn)pk(1−p)n−k
np.random.seed(20201125) # 设置seed以便每次运行结果相同
# 假设有9个靶子,每个靶子命中的概率都是0.1,相互独立,打靶100轮
# 每轮命中靶子的数量为x
x = np.random.binomial(9,0.1,100)
print(x)
[2 0 0 2 1 0 0 0 1 1 0 2 1 0 1 0 0 0 2 0 1 0 0 2 0 2 1 0 0 0 0 1 2 1 0 0 1
0 1 1 0 0 1 1 1 0 2 0 2 1 3 0 0 1 1 2 0 2 0 2 1 2 0 2 1 0 1 0 1 3 2 0 2 0
1 0 2 1 2 0 0 1 1 0 1 0 1 0 1 2 1 0 1 1 1 1 1 0 0 1]
labels, count = np.unique(x, return_counts=True)
print("命中的次数", labels, "次数相同的数量", count)
plt.bar(labels, count)
plt.xlabel('times')
plt.ylabel('the num of same times')
命中的次数 [0 1 2 3] 次数相同的数量 [43 36 19 2]
Text(0, 0.5, 'the num of same times')
泊松分布
泊松分布主要用于估计某个时间段某事件发生的概率。
公式为:
P
{
X
=
k
}
=
λ
k
k
!
e
−
λ
k
=
1
,
2
,
⋯
P\{X=k\}=\frac{\lambda^k}{k!}e^{-\lambda} \quad k=1,2,\cdots
P{X=k}=k!λke−λk=1,2,⋯
np.random.poisson(lam=1.0, size=None)
表示对一个泊松分布进行采样,size表示采样的次数,lam表示一个单位内发生事件的平均值,函数的返回值表示一个单位内事件发生的次数。
# 假定某航空公司预定票处平均每小时接到42次订票电话,
# 那么10分钟内恰好接到6次电话的概率是多少?
import matplotlib as mpl
np.random.seed(20201125)
lam = 42/6
size = 50000
x = np.random.poisson(lam, size)
# 则10分钟接到6次的概率为
print(np.sum(x==6)/size)
mpl.rcParams['font.sans-serif'] = ['SimHei']
mpl.rcParams['font.family']='sans-serif'
mpl.rcParams['axes.unicode_minus'] = False
plt.hist(x)
plt.xlabel('随机变量:每十分钟接到订票电话的次数')
plt.ylabel('50000个样本中出现的次数')
0.14924
Text(0, 0.5, '50000个样本中出现的次数')
超几何分布
在超几何分布中,各次实验不是独立的,各次实验成功的概率也不等。
公式为:
P
(
k
,
M
,
n
,
N
)
=
(
k
n
)
(
N
−
k
M
−
n
)
(
N
M
)
P(k,M,n,N)=\frac{(^n_k)(^{M-n}_{N-k})}{(^M_N)}
P(k,M,n,N)=(NM)(kn)(N−kM−n)
np.random.hypergeometric(ngood, nhad, nsample, size=None)
size: 表示采样的次数
nhad: 表示总体中具有成功标志的元素个数
nbad: 表示总体中不具有成功标志的元素个数
ngood+nbad表示总体样本容量
nsample: 表示抽取元素的次数(小于或等于总体样本容量)
函数返回值表示抽取nsample个元素中具有成功标识的元素个数。
# 一共20只动物里有7只是狗,抽取12只有3只狗的概率(无放回抽样)。
np.random.seed(20201125)
size = 500000
x = np.random.hypergeometric(ngood=7, nbad=13, nsample=12, size=size)
print(np.sum(x==3)/size)
0.197838
plt.hist(x, bins=8)
plt.xlabel('狗的数量')
plt.ylabel('500000个样本中出现的次数')
plt.title('超几何分布')
Text(0.5, 1.0, '超几何分布')
连续型随机变量
均匀分布
numpy.random.uniform(low=0.0, high=1.0, size=None)
low:下限,high:上限。左闭右开
np.random.seed(20201125)
a = 0
b = 100
size = 100000
x = np.random.uniform(a,b,size)
plt.hist(x, bins=20)
(array([4951., 4856., 4987., 5040., 5053., 5047., 5125., 5119., 4988.,
4964., 5014., 5109., 4975., 5028., 4918., 5053., 4988., 4934.,
4782., 5069.]),
array([6.02032350e-04, 5.00053465e+00, 1.00004673e+01, 1.50003999e+01,
2.00003325e+01, 2.50002651e+01, 3.00001977e+01, 3.50001303e+01,
4.00000629e+01, 4.49999956e+01, 4.99999282e+01, 5.49998608e+01,
5.99997934e+01, 6.49997260e+01, 6.99996586e+01, 7.49995912e+01,
7.99995238e+01, 8.49994565e+01, 8.99993891e+01, 9.49993217e+01,
9.99992543e+01]),
<a list of 20 Patch objects>)
# size可以是一个tuple,list
np.random.uniform(size=(4,3))
array([[0.54561167, 0.41033111, 0.70684223],
[0.4984743 , 0.15230311, 0.98309236],
[0.62005204, 0.55589025, 0.19220916],
[0.19119403, 0.71146711, 0.29330197]])
# 若high不为None时,取[low,high)之间随机整数,否则取值[0,low)之间随机整数。
np.random.seed(20201125)
np.random.randint(2, size=10)
array([1, 1, 1, 1, 1, 0, 0, 1, 1, 0])
正态分布
标准正态公式为:
f
(
x
)
=
e
x
p
(
−
x
2
/
2
)
2
π
f(x)=\frac{exp(-x^2/2)}{\sqrt{2\pi}}
f(x)=2π
exp(−x2/2)
np.random.randn(d0, d1, …, dn)
根据指定大小产生满足标准正态分布的数组(均值为0,标准差为1)。
np.random.seed(20201125)
size = 100000
x = np.random.randn(size)
plt.hist(x, bins=50)
(array([2.000e+00, 2.000e+00, 4.000e+00, 9.000e+00, 2.500e+01, 2.900e+01,
5.600e+01, 8.900e+01, 1.480e+02, 2.660e+02, 3.900e+02, 5.810e+02,
8.590e+02, 1.216e+03, 1.628e+03, 2.140e+03, 2.681e+03, 3.501e+03,
4.095e+03, 4.940e+03, 5.594e+03, 6.241e+03, 6.633e+03, 6.833e+03,
6.908e+03, 6.684e+03, 6.444e+03, 5.844e+03, 5.396e+03, 4.578e+03,
3.932e+03, 3.125e+03, 2.548e+03, 1.989e+03, 1.435e+03, 1.046e+03,
7.740e+02, 5.030e+02, 3.140e+02, 2.190e+02, 1.260e+02, 7.200e+01,
4.300e+01, 2.600e+01, 1.800e+01, 6.000e+00, 3.000e+00, 3.000e+00,
1.000e+00, 1.000e+00]),
array([-4.24777622, -4.07327468, -3.89877313, -3.72427159, -3.54977005,
-3.3752685 , -3.20076696, -3.02626541, -2.85176387, -2.67726232,
-2.50276078, -2.32825923, -2.15375769, -1.97925614, -1.8047546 ,
-1.63025305, -1.45575151, -1.28124996, -1.10674842, -0.93224688,
-0.75774533, -0.58324379, -0.40874224, -0.2342407 , -0.05973915,
0.11476239, 0.28926394, 0.46376548, 0.63826703, 0.81276857,
0.98727012, 1.16177166, 1.33627321, 1.51077475, 1.68527629,
1.85977784, 2.03427938, 2.20878093, 2.38328247, 2.55778402,
2.73228556, 2.90678711, 3.08128865, 3.2557902 , 3.43029174,
3.60479329, 3.77929483, 3.95379638, 4.12829792, 4.30279946,
4.47730101]),
<a list of 50 Patch objects>)
还可以指定分布以及所需参数来进行随机,例如高斯分布中的
μ
\mu
μ和
σ
\sigma
σ。
np.random.normal(loc=0.0, scale=1.0, size=None)
normal()可以创建均值为loc,标准差为scale,大小为size的数组
np.random.seed(20201125)
x1 = 0.5*np.random.randn(2,4)+5
print(x1)
[[4.84827178 4.93681632 5.86751102 4.92414895]
[4.4484459 5.68396982 4.0909505 5.30022725]]
np.random.seed(20201125)
x2 = np.random.normal(5, 0.5, (2,4))
print(x2)
# 同上
[[4.84827178 4.93681632 5.86751102 4.92414895]
[4.4484459 5.68396982 4.0909505 5.30022725]]
size = 50000
x = np.random.normal(5, 0.5, size)
plt.hist(x, bins=50)
(array([1.000e+00, 3.000e+00, 0.000e+00, 6.000e+00, 4.000e+00, 6.000e+00,
1.100e+01, 2.400e+01, 3.300e+01, 7.100e+01, 1.030e+02, 1.570e+02,
2.140e+02, 3.090e+02, 4.690e+02, 6.570e+02, 8.360e+02, 1.127e+03,
1.398e+03, 1.702e+03, 2.039e+03, 2.398e+03, 2.771e+03, 2.905e+03,
3.136e+03, 3.203e+03, 3.402e+03, 3.335e+03, 3.163e+03, 2.868e+03,
2.650e+03, 2.305e+03, 1.925e+03, 1.661e+03, 1.377e+03, 1.039e+03,
7.600e+02, 5.820e+02, 4.440e+02, 3.290e+02, 2.250e+02, 1.310e+02,
8.300e+01, 6.700e+01, 2.900e+01, 1.400e+01, 1.600e+01, 6.000e+00,
2.000e+00, 4.000e+00]),
array([2.787696 , 2.87148713, 2.95527826, 3.0390694 , 3.12286053,
3.20665166, 3.2904428 , 3.37423393, 3.45802506, 3.5418162 ,
3.62560733, 3.70939846, 3.7931896 , 3.87698073, 3.96077186,
4.044563 , 4.12835413, 4.21214526, 4.29593639, 4.37972753,
4.46351866, 4.54730979, 4.63110093, 4.71489206, 4.79868319,
4.88247433, 4.96626546, 5.05005659, 5.13384773, 5.21763886,
5.30142999, 5.38522113, 5.46901226, 5.55280339, 5.63659452,
5.72038566, 5.80417679, 5.88796792, 5.97175906, 6.05555019,
6.13934132, 6.22313246, 6.30692359, 6.39071472, 6.47450586,
6.55829699, 6.64208812, 6.72587926, 6.80967039, 6.89346152,
6.97725265]),
<a list of 50 Patch objects>)
指数分布
指数分布描述时间发生的时间长度间隔。
公式为:
f
(
x
)
=
{
λ
e
−
λ
x
x
>
0
0
x
≤
0
f(x)=\begin{cases} \lambda e^{-\lambda x} & x>0 \\ 0 & x \leq 0 \end{cases}
f(x)={λe−λx0x>0x≤0
np.random.exponential(scale=1.0, size=None)
例:
s
c
a
l
e
=
1
λ
scale = \frac 1 \lambda
scale=λ1
np.random.seed(20201125)
lam = 7
size = 50000
x = np.random.exponential(1/lam, size)
plt.hist(x, bins=20)
(array([2.2246e+04, 1.2299e+04, 6.8100e+03, 3.8430e+03, 2.0660e+03,
1.2170e+03, 6.8100e+02, 3.6500e+02, 2.1600e+02, 1.1800e+02,
6.2000e+01, 3.4000e+01, 1.8000e+01, 1.1000e+01, 8.0000e+00,
3.0000e+00, 0.0000e+00, 0.0000e+00, 1.0000e+00, 2.0000e+00]),
array([8.60048803e-07, 8.32727501e-02, 1.66544640e-01, 2.49816530e-01,
3.33088420e-01, 4.16360310e-01, 4.99632200e-01, 5.82904090e-01,
6.66175980e-01, 7.49447870e-01, 8.32719761e-01, 9.15991651e-01,
9.99263541e-01, 1.08253543e+00, 1.16580732e+00, 1.24907921e+00,
1.33235110e+00, 1.41562299e+00, 1.49889488e+00, 1.58216677e+00,
1.66543866e+00]),
<a list of 20 Patch objects>)
其它随机函数
随机从序列中获取元素
np.random.choice(a, size=None, replace=True, p=None)
从序列中获取元素,若a为整数,元素取值从np.range(a)中随机获取;若a为数组,取值从a数组元素中随机获取。该函数还可以控制生成数组中的元素是否重复replace,以及选取元素的概率p。
np.random.seed(20201125)
x = np.random.choice(10, 3)
print(x)
x1 = np.random.choice(10,3, p=[0.05, 0, 0.05, 0.9, 0, 0, 0, 0, 0, 0])
print(x1)
[3 8 6]
[3 3 3]
对数据进行洗牌操作
数据一般都是按照采集顺序排列的,但是在机器学习中很多算法都要求数据之间相互独立,所以需要先对数据集进行洗牌操作。
np.random.shuffle(x)
对x进行重排序,如果x为多维数组,只沿第 0 轴洗牌,改变原来的数组,输出为None
# 洗牌,改变自身内容,打乱顺序。
np.random.seed(20201125)
x = np.arange(10)
print(x)
np.random.shuffle(x)
print(x)
[0 1 2 3 4 5 6 7 8 9]
[7 2 4 5 0 1 9 6 8 3]
x = np.arange(20).reshape(4,5)
print(x)
np.random.shuffle(x)
print(x)
[[ 0 1 2 3 4]
[ 5 6 7 8 9]
[10 11 12 13 14]
[15 16 17 18 19]]
[[15 16 17 18 19]
[10 11 12 13 14]
[ 0 1 2 3 4]
[ 5 6 7 8 9]]
np.random.permutation(x)
若x为整数,则随机置换np.arange(x)
若x为数组,则进行复制并随机排列这些元素
np.random.seed(20201125)
x = np.arange(10)
print(x)
print("参数为int")
print(np.random.permutation(10))
print("参数为数组")
print(np.random.permutation(x))
print("进行随机排列之后的原数组")
print(x)
[0 1 2 3 4 5 6 7 8 9]
参数为int
[7 2 4 5 0 1 9 6 8 3]
参数为数组
[0 7 8 6 5 9 3 4 2 1]
进行随机排列之后的原数组
[0 1 2 3 4 5 6 7 8 9]
# 创建一个形为5×3的二维数组,以包含5到10之间的随机数
res = np.random.randint(5,10,[5,3])
print(res)
[[7 6 8]
[8 5 5]
[6 7 9]
[5 7 5]
[5 9 8]]