小实验:关于期望的乘法性质
- 引言
- 个人疑惑
- 验证过程
- 样本生成
- 实验过程
- 附:完整代码
引言
本节通过代码实现期望的乘法性质。
个人疑惑
在数学期望的定义中,有一条随机变量期望的乘法性质:
当随机变量
X
,
Y
\mathcal X,\mathcal Y
X,Y相互独立时,有:
E
(
X
⋅
Y
)
=
E
(
X
)
⋅
E
(
Y
)
\mathbb E(\mathcal X \cdot \mathcal Y) = \mathbb E(\mathcal X) \cdot \mathbb E(\mathcal Y)
E(X⋅Y)=E(X)⋅E(Y)
个人误区:随机变量 X , Y \mathcal X,\mathcal Y X,Y分别属于不同分布,在各分布下随机变量独立采样时,它们的期望会满足上述形式。
问题:如果两随机变量 X , Y \mathcal X,\mathcal Y X,Y是独立同分布 ( Independent Identically Distribution,IID ) (\text{Independent Identically Distribution,IID}) (Independent Identically Distribution,IID)条件下,上述结果是否也成立 ? ? ?
验证过程
样本生成
我们使用基于一维高斯分布
(
Gaussian Distribution
)
(\text{Gaussian Distribution})
(Gaussian Distribution)的两随机变量
X
,
Y
\mathcal X,\mathcal Y
X,Y进行验证。高斯分布的概率密度函数表示如下:
F
(
x
)
=
1
σ
2
π
exp
{
−
(
x
−
μ
)
2
2
σ
2
}
\mathcal F(x) = \frac{1}{\sigma \sqrt{2\pi}} \exp \left\{- \frac{(x - \mu)^2}{2 \sigma^2} \right\}
F(x)=σ2π1exp{−2σ2(x−μ)2}
对应代码表示如下:
import math
import random
import numpy as np
import matplotlib.pyplot as plt
def pdf(x,mu,sigma):
return (1 / (sigma * math.sqrt(2 * math.pi))) * math.exp(-1 * (((x - mu) ** 2) / (2 * (sigma ** 2))))
但在牛客网八股刷题系列——概率密度函数中介绍过,概率密度函数结果进描述输入事件发生的可能性,而不是真正的概率结果。这里使用积分近似的方式对概率进行近似描述:
这里使用
1000
1000
1000个点对积分区间(设置左边界
−
5
-5
−5,右边界是需要计算概率的值)
需要注意的是:仅作实验使用,左边界数值不能设置太高,否则会导致积分误差较大。
def GetIntegral(x,mu,sigma,DivideNum=1000):
dx = list()
y = list()
x = list(np.linspace(-5,x,DivideNum))
for k in range(0,DivideNum - 1):
y.append(pdf(x[k],mu,sigma))
dx.append(x[k+1] - x[k])
return np.sum(np.multiply(y,dx))
基于上述概率结果,我们从均值为
μ
\mu
μ方差为
σ
\sigma
σ的高斯分布中采集一组样本:
由于‘概率密度函数’形状是关于
x
=
μ
x = \mu
x=μ对称图形,需要将大于一半积分
(
0.5
)
(0.5)
(0.5)的结果减去
0.5
0.5
0.5,并将剩余部分乘以2;若积分小于
0.5
0.5
0.5,仅需要将该部分乘以2即可。也就是说,
x
=
μ
x = \mu
x=μ时的作为该分布的概率最大。
def GetSample(mu,sigma,SampleNum=500):
SampleList = list()
count = 0
while True:
n = random.uniform(0,1)
# PDF的有效范围设置
Samplex = random.uniform(-10,10)
SampleIntegral = GetIntegral(Samplex,mu,sigma)
if SampleIntegral >= 0.5:
Prob = 2 * (1 - SampleIntegral)
else:
Prob = 2 * SampleIntegral
if n < Prob:
SampleList.append(Samplex)
count += 1
if count == SampleNum:
break
return SampleList
至此,可以通过该采样得到不同参数 ( μ , σ ) (\mu,\sigma) (μ,σ),并且数量相同的一维高斯分布样本。
实验过程
- 首先使用服从于相同分布的两组样本集合
SampleListx
于SampleListy
。将两组样本集合中的样本对应元素相乘,从而得到一个新的样本集合:
这里样本属于随机相乘。因为我们并不知晓两集合中各样本的具体数值结果。
def CheckExpectationValue(Inputx,Inputy):
"""
Inputx,Inputy -> IID
From the same Gaussian Distribution.
:return:
"""
# RandomProduct
ProductSample = [i * j for _,(i,j) in enumerate(zip(Inputx,Inputy))]
return sum(ProductSample) / len(ProductSample)
此时,构建两个参数相同的高斯分布的样本集合,执行上述操作:
末尾附完整代码。
SampleListx = GetSample(mu=1.0, sigma=1.0)
SampleListy = GetSample(mu=1.0, sigma=1.0)
MixExpect = CheckExpectationValue(SampleListx,SampleListy)
print(sum(SampleListx) / len(SampleListx))
print(sum(SampleListy) / len(SampleListy))
print(MixExpect)
原集合与新集合的期望结果分别表示为:
# 1.0 * 1.0 = 1.0
0.9918332790661574
0.9996555919557066
1.0031321613765627
可以发现,个人误区中的想法是错误的:只要随机变量之间相互独立(单独被采样出来),即便它们属于相同分布,期望的乘法性质依旧成立。
将这个示例泛化:
- 选择两个不同参数的高斯分布;
- 每隔 10 10 10个样本,输出一次原始集合、新集合的期望结果, 观察它们的收敛过程:
def CheckExpectAstringency(SampleListx,SampleListy,mu):
ContainerX = list()
ContainerY = list()
ExpectXList = list()
ExpectYList = list()
ExpectList = list()
for idx,(i,j) in enumerate(zip(SampleListx,SampleListy)):
ContainerX.append(i)
ContainerY.append(j)
if len(ContainerX) % 10 == 0:
ExpectXList.append(sum(ContainerX) / len(ContainerX))
ExpectYList.append(sum(ContainerY) / len(ContainerY))
ExpectList.append(CheckExpectationValue(ContainerX,ContainerY))
plt.plot([i for i in range(len(ExpectList))],[mu for _ in range(len(ExpectList))])
plt.plot([i for i in range(len(ExpectList))],ExpectList,c="tab:orange")
plt.plot([i for i in range(len(ExpectList))],ExpectXList,c="tab:red")
plt.plot([i for i in range(len(ExpectList))],ExpectYList,c="tab:green")
plt.show()
SampleListx = GetSample(mu=1.5, sigma=1.0)
SampleListy = GetSample(mu=2.0, sigma=1.0)
# mu:1.5 * 2.0 = 3.0
CheckExpectAstringency(SampleListx,SampleListy,mu=3.0)
最终图像结果返回如下:
其中
绿色线,红色线分别表示各原始集合的期望收敛过程;
橙色线表示新集合的期望收敛过程。而
蓝色线则表示新集合的理论期望结果。
可以看出,随着样本的增多,分布的描述越加明显,期望结果逐渐向理论期望结果收敛。并且在原始分布均是高斯分布的条件下,即便分布参数之间存在差异,但不影响期望的乘法性质。
本篇文章目的是针对
深度学习笔记——数值稳定性、模型初始化与激活函数中期望问题的验证,该文章中有理解错误,后续修改。
附:完整代码
import math
import random
import numpy as np
import matplotlib.pyplot as plt
def pdf(x,mu,sigma):
return (1 / (sigma * math.sqrt(2 * math.pi))) * math.exp(-1 * (((x - mu) ** 2) / (2 * (sigma ** 2))))
def Console():
def GetIntegral(x,mu,sigma,DivideNum=1000):
dx = list()
y = list()
x = list(np.linspace(-5,x,DivideNum))
for k in range(0,DivideNum - 1):
y.append(pdf(x[k],mu,sigma))
dx.append(x[k+1] - x[k])
return np.sum(np.multiply(y,dx))
def GetSample(mu,sigma,SampleNum=5000):
SampleList = list()
count = 0
while True:
n = random.uniform(0,1)
Samplex = random.uniform(-10,10)
SampleIntegral = GetIntegral(Samplex,mu,sigma)
if SampleIntegral >= 0.5:
Prob = 2 * (1 - SampleIntegral)
else:
Prob = 2 * SampleIntegral
if n < Prob:
SampleList.append(Samplex)
count += 1
if count == SampleNum:
break
return SampleList
def CheckExpectationValue(Inputx,Inputy):
"""
Inputx,Inputy -> IID
:return:
"""
# RandomProduct
ProductSample = [i * j for _,(i,j) in enumerate(zip(Inputx,Inputy))]
return sum(ProductSample) / len(ProductSample)
def CheckExpectAstringency(SampleListx,SampleListy,mu):
ContainerX = list()
ContainerY = list()
ExpectXList = list()
ExpectYList = list()
ExpectList = list()
for idx,(i,j) in enumerate(zip(SampleListx,SampleListy)):
ContainerX.append(i)
ContainerY.append(j)
if len(ContainerX) % 10 == 0:
ExpectXList.append(sum(ContainerX) / len(ContainerX))
ExpectYList.append(sum(ContainerY) / len(ContainerY))
ExpectList.append(CheckExpectationValue(ContainerX,ContainerY))
plt.plot([i for i in range(len(ExpectList))],[mu for _ in range(len(ExpectList))])
plt.plot([i for i in range(len(ExpectList))],ExpectList,c="tab:orange")
plt.plot([i for i in range(len(ExpectList))],ExpectXList,c="tab:red")
plt.plot([i for i in range(len(ExpectList))],ExpectYList,c="tab:green")
plt.show()
SampleListx = GetSample(mu=1.0, sigma=1.0)
SampleListy = GetSample(mu=1.0, sigma=1.0)
MixExpect = CheckExpectationValue(SampleListx,SampleListy)
# mu:1.0 * 1.0 = 1.0
CheckExpectAstringency(SampleListx,SampleListy,mu=1.0)
if __name__ == '__main__':
Console()
返回结果:
相关参考:
数学期望——百度百科