2.6.1 基本概率论
%matplotlib inline
import torch
from torch.distributions import multinomial
from d2l import torch as d2l
先说几个统计学中的名词:
- 抽样(sampling):从概率分布中抽取样本的过程。
- 分布(distribution):类似于对事件概率分配。
- 多项分布(multionmial distribution):将概率分配给一些离散选择的分布。
在 Pytorch 中,多项分布 Multinomial() 是 torch.distributions.multinomial 中的一个类,接受四个参数:
- total_count=1 :接受 int 参数,指的是单次抽样的样本数量。
- probs=None :接受 Tensor 参数,指的是各事件发生的概率或频数(当传入频数时可以通过probs属性查看对应的概率分布)。
- logits=None :接受 Tensor 参数,指的是各事件发生的概率的自然对数或频数(当传入频数时可以通过logits属性查看对应的对数概率分布)。
- validate_args=None :用于指定是否检查参数的合法性。
sample() 是 Multinomial 类中的抽样函数,接收一个参数 ample_shape=torch.Size() 以指定抽样次数和输出张量的形状。
fair_probs = torch.ones([6]) / 6
test1_Multinomial = multinomial.Multinomial(1, fair_probs) # 一次抽一个样本
test2_Multinomial = multinomial.Multinomial(10, fair_probs) # 一次抽十个样本
test1_Multinomial.probs, test2_Multinomial.probs, test1_Multinomial.sample(), test2_Multinomial.sample()
(tensor([0.1667, 0.1667, 0.1667, 0.1667, 0.1667, 0.1667]),
tensor([0.1667, 0.1667, 0.1667, 0.1667, 0.1667, 0.1667]),
tensor([0., 0., 0., 1., 0., 0.]),
tensor([1., 1., 3., 3., 1., 1.]))
counts = multinomial.Multinomial(1000, fair_probs).sample() # 抽一千次,验证一下大数定律
counts / 1000 # 估算一下概率
tensor([0.1730, 0.1540, 0.1510, 0.1710, 0.1630, 0.1880])
# 画个图可以看到概率会逐渐收敛
counts = multinomial.Multinomial(10, fair_probs).sample((500,)) # 每次抽10个样本,抽500组
cum_counts = counts.cumsum(dim=0) # 沿0轴累计求和,即分别计算做1-500组采样的抽取结果
estimates = cum_counts / cum_counts.sum(dim=1, keepdim=True) # 分别计算做1-500组采样的结果的概率
d2l.set_figsize((6, 4.5)) # 设置画布大小
for i in range(6): # 分别画出六个事件的概率曲线
d2l.plt.plot(estimates[:, i].numpy(),
label="P(die=" + str(i + 1) + ")")
d2l.plt.axhline(y=0.167, color='black', ls='dashed') # 报'Line2D' object has no property 'lineststylr'错,因为当前 matplotlib 版本把 linestyle 和 linewidth 替换成了 ls 和 lw
# 设置横纵轴名称
d2l.plt.gca().set_xlabel('Groups of experiments')
d2l.plt.gca().set_ylabel('Estimated probability')
d2l.plt.legend() # 书上这里的分号是干啥的?
<matplotlib.legend.Legend at 0x1ade1038f10>
再进一波理论:
- 样本空间(sample space)或结果空间(outcome space):随机实验的所有可能结果构成的集合。
- 结果(outcome):样本空间或结果空间中的元素。
- 事件(event):一组给定样本空间的随机结果。
例如,在掷骰子实验中,集合 \(S=\left\{1,2,3,4,5,6\right\}\) 即为样本空间或结果空间,其中每个元素都是结果。
概率可以看作将集合映射到真实值的函数。在给定的样本空间 \(S\) 中,事件 \(A\) 的概率表示为 \(P(A)\),具有以下属性:
- 非负,即 \(P(A)\ge0\);
- 整个样本空间的概率为 1,即 \(P(S)=1\);
- 对于互斥(mutually exclusive)事件(对于所有 \(i\ne j\)都有 \(A_i\cap A_j=\varnothing\))的任意一个可数序列 \(A_1,A_2,\dots,\) 序列中任一事件发生的概率等于它们各自发生概率之和,即 \(P\left(\bigcup^\infty_{i=1}A_i\right)=\sum^\infty_{i=1}P(A_i)\)。
2.6.2 处理多个随机变量
整节理论知识,详见书本。
2.6.3 期望和方差
整节理论知识,详见书本。
练习
(1)进行 m组实验,每组抽取个样本。改变和,观察和分析实验结果。
# 画个图可以看到概率会逐渐收敛
counts = multinomial.Multinomial(10, fair_probs).sample((5000,)) # 每次抽10个样本,抽500组
cum_counts = counts.cumsum(dim=0) # 沿0轴累计求和,即分别计算做1-500组采样的抽取结果
estimates = cum_counts / cum_counts.sum(dim=1, keepdim=True) # 分别计算做1-500组采样的结果的概率
d2l.set_figsize((6, 4.5)) # 设置画布大小
for i in range(6): # 分别画出六个事件的概率曲线
d2l.plt.plot(estimates[:, i].numpy(),
label="P(die=" + str(i + 1) + ")")
d2l.plt.axhline(y=0.167, color='black', ls='dashed')
# 设置横纵轴名称
d2l.plt.gca().set_xlabel('Groups of experiments')
d2l.plt.gca().set_ylabel('Estimated probability')
d2l.plt.legend()
<matplotlib.legend.Legend at 0x1ade43621f0>
确实是越来越收敛
(2)给定两个概率分别为 \(P(A)\) 和 \(P(B)\) 的事件,计算 \(P(A\cup B)\) 和 \(P(A\cap B)\) 的上限和下限。(提示:使用友元图)
\[\begin{align}
\max(P(A), P(B))\quad\le\quad&P(A\cup B)\quad\le\quad P(A)+P(B)\\
0\qquad\le\quad&P(A\cap B)\quad\le\quad\min(P(A), P(B))\\
\end{align}
\]
下限 | 上限 | ||
---|---|---|---|
\(P(A\cup B)\) | |||
\(P(A\cap B)\) |
(3)假设我们有一系列随机变量,例如 \(A\)、\(B\) 和 \(C\),其中 \(B\) 只依赖于 \(A\),而 \(C\) 只依赖于 \(B\),能简化联合概率 \(P(A,B,C)\) 吗?(提示:这是一个马尔可夫链)
\[\begin{align}
P(A,B,C)&=P(C|A,B)\ P(A,B)\\
&=P(C|B)\ P(A,B)\\
&=P(C|B)\ P(B|A)\ P(A)\\
\end{align}
\]
(4)在 2.6.2 节中,第一个测试更准确。为什么不运行第一个测试两次,而是同时运行第一个和第二个测试?
用术语说是需要条件独立性,做两次第一个测试得到的结果大概率一样,很难通过重复同一个测试增加测试的可信度。
用大白话来讲,第二次做不同的测试就是为了验证第一个测试的结果,做两遍一样的测试没有意义。