2.6 概率

发布时间 2023-05-25 17:23:34作者: AncilunKiang

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>


image


再进一波理论:

  • 样本空间(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>


image

确实是越来越收敛


(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)\) 001 002 003
\(P(A\cap B)\) 004 005 006

(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 节中,第一个测试更准确。为什么不运行第一个测试两次,而是同时运行第一个和第二个测试?

用术语说是需要条件独立性,做两次第一个测试得到的结果大概率一样,很难通过重复同一个测试增加测试的可信度。

用大白话来讲,第二次做不同的测试就是为了验证第一个测试的结果,做两遍一样的测试没有意义。