正态分布、正态分布采样及Python实现
多元正态分布(多元高斯分布)
直接从多元正态分布讲起。多元正态分布公式如下:
P
r
=
1
(
2
π
)
D
/
2
∣
∑
∣
1
/
2
e
x
p
(
−
0.5
(
x
−
μ
)
T
∑
−
1
(
x
−
μ
)
)
)
P_r = \frac{1}{(2\pi )^{D/2}\left | \sum \right |^{1/2}}exp(-0.5(x-\mu)^T{\sum} ^{-1}(x-\mu)))
Pr=(2π)D/2∣∑∣1/21exp(−0.5(x−μ)T∑−1(x−μ)))
其中 μ \mu μ代表每个维度上的均值,是一个 D × 1 D\times 1 D×1维的向量,而 ∑ \sum ∑代表协方差矩阵,是一个 D × D D\times D D×D正定矩阵。上述公式可简写为: P r ( x ) = N o r m x [ μ , ∑ ] P_r(x)=Norm_x[\mu,\sum] Pr(x)=Normx[μ,∑]这就是多元正态分布的定义,均值好理解,就是高斯分布的概率分布值最大的位置,进行采样时也就是采样的中心点。而协方差矩阵在多维上形式较多。
协方差矩阵
一般来说,协方差矩阵有三种形式,分别称为球形、对角和全协方差。以二元为例:
∑
s
p
h
e
r
=
(
σ
2
0
0
σ
2
)
{\sum}_{spher}=\begin{pmatrix} \sigma ^2 & 0\\ 0 & \sigma ^2 \end{pmatrix}
∑spher=(σ200σ2)
∑
d
i
a
g
=
(
σ
1
2
0
0
σ
2
2
)
{\sum}_{diag}=\begin{pmatrix} \sigma_1 ^2 & 0\\ 0 & \sigma_2 ^2 \end{pmatrix}
∑diag=(σ1200σ22)
∑
f
u
l
l
=
(
σ
11
2
σ
12
2
σ
21
2
σ
22
2
)
{\sum}_{full}=\begin{pmatrix} \sigma_{11} ^2 & \sigma_{12} ^2\\ \sigma_{21} ^2 & \sigma_{22} ^2 \end{pmatrix}
∑full=(σ112σ212σ122σ222)
对于N元正态分布有:
∑
=
(
c
o
v
(
X
1
,
X
1
)
c
o
v
(
X
1
,
X
2
)
⋯
c
o
v
(
X
1
,
X
n
)
c
o
v
(
X
2
,
X
1
)
c
o
v
(
X
2
,
X
2
)
⋯
c
o
v
(
X
2
,
X
n
)
⋮
⋮
⋮
⋮
c
o
v
(
X
n
,
X
1
)
c
o
v
(
X
n
,
X
2
)
⋯
c
o
v
(
X
n
,
X
n
)
)
{\sum}=\begin{pmatrix} cov(X_1,X_1) & cov(X_1,X_2) & \cdots & cov(X1,X_n)\\ cov(X_2,X_1) & cov(X_2,X_2) & \cdots & cov(X_2,X_n) \\ \vdots & \vdots & \vdots & \vdots\\ cov(X_n,X_1) & cov(X_n,X_2) & \cdots & cov(X_n,X_n) \end{pmatrix}
∑=⎝⎜⎜⎜⎛cov(X1,X1)cov(X2,X1)⋮cov(Xn,X1)cov(X1,X2)cov(X2,X2)⋮cov(Xn,X2)⋯⋯⋮⋯cov(X1,Xn)cov(X2,Xn)⋮cov(Xn,Xn)⎠⎟⎟⎟⎞
为了方便展示不同协方差矩阵的效果,我们以二维为例。(书上截的图,凑活着看吧,是在不想画图了)
其实从这个图上可以很好的看出,协方差矩阵对正态分布的影响,也就很好明白了这三个协方差矩阵是哪里来的名字了。可以看出,球形协方差矩阵,会产生圆形(二维)或者球形(三维)的等高线,对角协方差矩阵和全协方差矩阵,会产生椭圆形的等高线。更一般地,在一个D维空间中,球形协方差矩阵,会产生一个D维球面等高线;对角协方差矩阵,会产生一个坐标轴对其的椭球型等高线;全协方差矩阵,会在任意位置产生一个坐标轴对其的椭球型等高线。
当协方差矩阵是球形的或者是对角的,单独的变量之间是独立的
协方差分解
时间不足,具体解释以后再补
下面是协方差分解的原理图
变量的线性变换(正态分布采样原理)
多元正态的形式在线性变换 y = A x + b y=Ax+b y=Ax+b下保持不变,例如下图:
假设原始分布是
P
r
(
x
)
=
N
o
r
m
x
[
μ
,
∑
]
P_r(x)=Norm_x[\mu,\sum]
Pr(x)=Normx[μ,∑]
那么经过
y
=
A
x
+
b
y=Ax+b
y=Ax+b变换后,变量y的分布为:
P
r
(
y
)
=
N
o
r
m
y
[
A
μ
+
b
,
A
∑
A
T
]
P_r(y)=Norm_y[A\mu+b,A\sum A^T]
Pr(y)=Normy[Aμ+b,A∑AT]
这个关系提供了从均值为 μ \mu μ、协方差为 ∑ \sum ∑的正态分布抽取样本的简单方法。首先从单位正态分布中,抽取样本 x x x,然后应用 y = ∑ 1 / 2 x + μ y={\sum}^{1/2}x+\mu y=∑1/2x+μ进行变换
python实现
多元正态分布在python的numpy库中有很方便一个函数:
np.random.multivariate_normal(mean=mean, cov=conv, size=N)
这个函数中,mean代表均值,是在每个维度中的均值。cov代表协方差矩阵,就像上面讲的那种形式,协方差矩阵值的大小将决定采样范围的大小。size代表需要采样生成的点数,此时输出大小为(N*D)的坐标矩阵。
另外,其他参数包括:check_valid,这个参数用于决定当cov即协方差矩阵不是半正定矩阵时程序的处理方式,它一共有三个值:warn,raise以及ignore。当使用warn作为传入的参数时,如果cov不是半正定的程序会输出警告但仍旧会得到结果;当使用raise作为传入的参数时,如果cov不是半正定的程序会报错且不会计算出结果;当使用ignore时忽略这个问题即无论cov是否为半正定的都会计算出结果
tol:检查协方差矩阵奇异值时的公差,float类型。
下面是一个小demo
import numpy as np
import matplotlib.pyplot as plt
mean = np.array([2,1]) # 均值
conv = np.array([[0.5, 0.0], # 协方差矩阵
[0.0, 0.5]])
axis = np.random.multivariate_normal(mean=mean, cov=conv, size=200)
x, y = np.random.multivariate_normal(mean=mean, cov=conv, size=1000).T
# print(axis[:])
plt.plot(axis[:, 0], axis[:, 1], 'ro')
plt.show()
plt.plot(x, y, 'ro')
plt.show()
注意,单独取出每个坐标轴的坐标数组时,需要在最后加上.T,否则会报错 效果展示:
协方差值的大小对采样的影响:
mean = np.array([2,1]) # 均值
conv = np.array([[0.5, 0.0], # 协方差矩阵
[0.0, 0.5]])
conv2 = np.array([[10, 0.0], # 协方差矩阵
[0.0, 10]])
axis = np.random.multivariate_normal(mean=mean, cov=conv, size=200)
x, y = np.random.multivariate_normal(mean=mean, cov=conv2, size=200).T
# print(axis[:])
plt.plot(axis[:, 0], axis[:, 1], 'ro')
plt.show()
plt.plot(x, y, 'ro')
plt.show()
效果如下:
这里没有设定随机种子店,每次随机数会有所不同。
参考文献
《 计算机视觉模型、学习和推理》