动手学深度学习-预备知识6-概率

218 阅读3分钟

机器学习的核心:预测

简单来说,机器学习的核心任务就是预测。通过建立模型,我们可以在不确定的情况下尽量精准地推测出未来的情况。例如:

  • 医疗领域:根据病人的病史预测他们在下一年心脏病发作的概率。
  • 异常检测:在飞机喷气发动机的监控中评估一组读数属于正常运行情况的概率。
  • 强化学习:希望智能体在一个环境中能以高概率选择获得高奖励的行为。
  • 推荐系统:在在线书店中,估计用户购买特定图书的概率。

为了达到这些预测目标,我们需要运用概率论。概率理论是一门专门研究不确定性事件的学科,通过它,我们可以更系统地表达各种可能性。然而,这里我们只介绍基础知识,帮助你开始理解和构建简单的机器学习模型。

考虑一个经典的机器学习任务:图像分类。比如,通过照片判断一张图是猫还是狗。人类在高分辨率图像中很容易辨认,但低分辨率的图片却让任务变得困难。在某种低分辨率下(如2x2像素),我们区分猫和狗几乎只能凭运气。这时,概率给了我们一个衡量确定性的工具。如果我们完全确定图像是一只猫,概率就是1;如果我们毫无头绪,我们可以给“猫”和“狗”各赋0.5的概率;如果较偏向认为是猫,但不完全确定,我们可能会赋0.7给“猫”。

再看另一个例子:天气预报。假设我们通过分析过去的数据,预测出明天北京下雨的概率为0.5。这类问题也是预测,但与图像分类稍有不同——天气是一种随机现象,可能受多种因素影响。

这两个例子展示了概率的不同应用方式,它既可以用于帮助我们在确定或不确定的情况下进行推测,也适用于多种机器学习任务。

一、基本概率论

概率(probability) 可以被看作是将集合映射到真实值的函数。在掷骰子的实验中,我们有一个样本空间(sample space),即所有可能的结果。在掷一个公平的六面骰子时,样本空间为{1, 2, 3, 4, 5, 6}。假设我们想知道掷出1的概率。对于一个公平的骰子,结果是均匀分布的,因此每个结果出现的概率都是 16\frac{1}{6}

要验证骰子是否公平,我们需要多次投掷并记录结果。对于每个数字,我们可以计算它出现的次数并除以投掷的总次数,以此作为该事件概率的估计值。根据大数定律,随着投掷次数的增加,这个估计值会越来越接近真实的概率。

以下是相应的代码示例,用于模拟投掷骰子的过程:

在统计学中,我们把从概率分布中抽取样本的过程称为抽样(sampling)。 笼统来说,可以把分布(distribution)看作对事件的概率分配, 稍后我们将给出的更正式定义。 将概率分配给一些离散选择的分布称为多项分布(multinomial distribution)。

import torch
from torch.distributions import multinomial
import d2l  # 参见《动手学深度学习-预备知识4-微积分》

"""
为了抽取一个样本,即掷骰子,我们只需传入一个概率向量。
输出是另一个相同长度的向量:它在索引 i 处的值是采样结果中出现的次数。
"""
fair_probs = torch.ones([6]) / 6
print(fair_probs)  # tensor([0.1667, 0.1667, 0.1667, 0.1667, 0.1667, 0.1667])
# 用于从多项分布(multinomial distribution)中采样1次
result_1 = multinomial.Multinomial(1, fair_probs).sample()
print(result_1)  # tensor([0., 0., 0., 0., 1., 0.])

"""
在估计一个骰子的公平性时,我们希望从同一分布中生成多个样本。
如果用Python的for循环来完成这个任务,速度会慢得惊人。
因此我们使用深度学习框架的函数同时抽取多个样本,得到我们想要的任意形状的独立样本数组。
"""
result_10 = multinomial.Multinomial(10, fair_probs).sample()
print(result_10)  # tensor([3., 2., 2., 3., 0., 0.])

"""
现在我们知道如何对骰子进行采样,我们可以模拟1000次投掷。
然后,我们可以统计1000次投掷后,每个数字被投中了多少次。
具体来说,我们计算相对频率,以作为真实概率的估计。
"""
result_1000 = multinomial.Multinomial(1000, fair_probs).sample()
print(result_1000)  # tensor([151., 163., 176., 190., 164., 156.])
true_probs = result_1000 / 1000
print(true_probs)  # tensor([0.1640, 0.1840, 0.1560, 0.1620, 0.1780, 0.1560])

因为我们是从一个公平的骰子中生成的数据,我们知道每个结果都有真实的概率, 大约是 16\frac{1}{6},所以上面输出的估计值看起来不错。

我们也可以看到这些概率如何随着时间的推移收敛到真实概率。 让我们进行500组实验,每组抽取10个样本。

counts = multinomial.Multinomial(10, fair_probs).sample(sample_shape=torch.Size([500]))
print(counts.shape)  # torch.Size([500, 6])
print(counts)
"""
tensor([[0., 0., 3., 2., 2., 3.],
        [0., 4., 3., 1., 1., 1.],
        [2., 0., 3., 2., 1., 2.],
        ...,
        [2., 2., 2., 1., 1., 2.],
        [1., 1., 1., 4., 1., 2.],
        [0., 2., 2., 2., 2., 2.]])
"""
cum_counts = counts.cumsum(dim=0)
print(cum_counts.shape)  # torch.Size([500, 6])
print(cum_counts)
"""
tensor([[  0.,   0.,   3.,   2.,   2.,   3.],
        [  0.,   4.,   6.,   3.,   3.,   4.],
        [  2.,   4.,   9.,   5.,   4.,   6.],
        ...,
        [838., 844., 856., 822., 841., 779.],
        [839., 845., 857., 826., 842., 781.],
        [839., 847., 859., 828., 844., 783.]])
"""
cum_counts_sum_dim1 = cum_counts.sum(dim=1, keepdim=True)
print(cum_counts_sum_dim1.shape)  # torch.Size([500, 1])
estimates = cum_counts / cum_counts_sum_dim1
print(estimates)
"""
tensor([[0.1000, 0.2000, 0.1000, 0.1000, 0.4000, 0.1000],
        [0.2000, 0.2000, 0.1500, 0.1500, 0.2000, 0.1000],
        [0.2333, 0.2000, 0.1000, 0.1667, 0.1333, 0.1667],
        ...,
        [0.1661, 0.1673, 0.1588, 0.1604, 0.1827, 0.1647],
        [0.1661, 0.1671, 0.1587, 0.1605, 0.1828, 0.1647],
        [0.1660, 0.1670, 0.1588, 0.1604, 0.1830, 0.1648]])
"""

d2l.set_figsize((6, 4.5))
for i in range(6):
    d2l.plt.plot(estimates[:, i].numpy(), label=f"P(die={i + 1})")  # 绘制二维线条图

d2l.plt.axhline(y=1 / 6, color='black', linestyle='dashed')
d2l.plt.gca().set_xlabel("实验组")
d2l.plt.gca().set_ylabel("估计概率")
d2l.plt.legend()  # 显示图例
d2l.plt.show()

myplot.png

每条实线对应于骰子的6个值中的一个,并给出骰子在每组实验后出现值的估计概率。 当我们通过更多的实验获得更多的数据时,这6条实体曲线向真实概率收敛。

1.1 概率论公理

概率论的三条公理为我们提供了计算概率的基本规则:

  • 非负性: 任何事件的概率都是非负的,即 P(A)0P(A) \geq 0
  • 规范性: 确定事件(必然发生的事件)的概率为1,即 P(S)=1P(S) = 1
  • 可加性: 如果两个事件 AABB 互斥(即它们不能同时发生),那么它们的联合概率是单独发生的概率之和,即 P(AB)=P(A)+P(B)P(A \cup B) = P(A) + P(B)

这些公理帮助我们确定事件发生的可能性。

1.2 随机变量

随机变量是一个数值表示随机现象的变量。例如,抛一枚硬币,我们可以用0表示正面,用1表示反面。随机变量分为离散随机变量(有有限可能值)和连续随机变量(可以取无限多的值)。理解随机变量帮助我们从数学上描述事件的结果。

二、处理多个随机变量

当我们处理多个随机变量时,概率的计算变得更为复杂。以下是几个重要的概念:

2.1 联合概率

联合概率描述了两个事件同时发生的概率。例如,设事件A表示“今天下雨”,事件B表示“今天打雷”,则事件“A且B发生”的概率就是A和B的联合概率,用 P(AB)P(A \cap B)表示。

2.2 条件概率

条件概率表示在已知一个事件发生的情况下,另一个事件发生的概率。设事件B已经发生,事件A发生的概率则用 P(AB)P(A | B) 表示。条件概率公式为:

P(AB)=P(AB)P(B)P(A | B) = \frac{P(A \cap B)}{P(B)}

2.3 贝叶斯定理

贝叶斯定理是一种通过已知信息更新概率的工具,公式为:

P(AB)=P(BA)P(A)p(B)P(A | B) = \frac{P(B | A) \cdot P(A)}{p(B)}

贝叶斯定理帮助我们从反向角度(如从结果推测原因)理解概率,在机器学习中用于分类、决策等任务。

2.4 边际化

边际化用于计算某一个事件的总体概率,而不关心其他事件的具体情况。例如,设有事件A和B,则边际概率 P(A)P(A)可通过联合概率P(AB)P(A \cap B)加总得到。

P(A)=P(AB1)+P(AB2)++P(ABn)P(A) = P(A \cap B1) + P(A \cap B2) + \cdots + P(A \cap B_n)

2.5 独立性

两个事件A和B独立,意味着一个事件的发生不影响另一个事件的概率。即:

P(AB)=P(A)P(B)P(A \cap B) = P(A) \cdot P(B)

独立性在概率计算中极为重要,它简化了许多复杂的计算。

2.6 应用

概率理论广泛应用于机器学习中的模型选择、预测、分类等。理解概率可以帮助我们更准确地预测事件发生的可能性,提高模型的准确性。

医疗诊断 - 贝叶斯定理

问题:假设一个疾病在总体人群中的发病率为1%,测试准确率为95%。如果测试结果为阳性,患者实际患病的概率是多少?

分析

事件患病记为 AA,概率为1%;事件阳性记为 BB

使用贝叶斯公式:

P(AB)=P(BA)P(A)p(B)P(A | B) = \frac{P(B | A) \cdot P(A)}{p(B)}

P(AB)P(A|B)

P(AB)=P(患病阳性)=P(阳性患病)P(患病)P(阳性)P(A|B)=P(患病|阳性) = \frac{P(阳性|患病) \cdot P(患病)}{P(阳性)}

其中:

  • P(阳性患病)=0.95P(阳性|患病) = 0.95,即测试准确率

  • P(患病)=0.01P(患病) = 0.01,即发病率

  • P(阳性)=P(阳性患病)P(患病)+P(阳性无病)P(无病)P(阳性) = P(阳性|患病) \cdot P(患病) + P(阳性|无病) \cdot P(无病)

    • P(阳性无病)=10.95=0.05P(阳性|无病) = 1 - 0.95 = 0.05
    • P(无病)=10.01=0.99P(无病) = 1 - 0.01 = 0.99
    • P(阳性)=0.95×0.01+0.05×0.99=0.059P(阳性) = 0.95 \times 0.01 + 0.05 \times 0.99 = 0.059
  • P(患病阳性)=0.95×0.010.059=16.10%P(患病∣阳性) = \frac{0.95 \times 0.01}{0.059} = 16.10\%

三、期望和方差

在处理概率时,期望方差是两个重要的统计量。

  • 期望(平均值): 期望就是你可以期待的 “平均结果” 。假如你每天上学路上走10分钟,偶尔走慢些会花15分钟,有时走快些只花5分钟。那么你走这一条路的期望时间可能接近10分钟,代表你整体上的平均表现。期望帮助我们在面对不确定性的时候抓住“整体趋势”,比如平均下来这件事大约的结果会是什么。

    • 如果对于一个离散随机变量 XX 和它的取值 xix_i 及其概率 p(xi)p(xi),期望值 E(X)E(X) 可以表示为:
    E(X)=i=1nxip(xi)E(X) = \sum_{i=1}^{n} x_i \cdot p(x_i)
    • 对于连续随机变量 XX 的情况,若概率密度函数为 f(x)f(x),则期望值 E(X)E(X) 表示为:
    E(X)=xf(x)dxE(X) = \int_{-\infty}^{\infty} x \cdot f(x) \, dx
  • 方差: 方差反映数据的 “波动情况” 或 “离散程度” 。它告诉我们数据是集中在期望附近,还是分散得很开。如果每天上学的时间总是10分钟,那方差几乎为0,因为波动很小;但如果某天走路花5分钟,某天15分钟,那么方差就比较大,表示时间上有波动。方差帮助我们理解事物的稳定性或者波动性,能够反映在长期中,事情是“相对稳定”还是“时常变化”的。

    • 对于离散随机变量 XX 的方差 Var(X)\mathrm{Var}(X),计算公式是:
    Var(X)=E[(Xμ)2]=i=1n(xiμ)2p(xi)\mathrm{Var}(X) = E[(X - \mu)^2] = \sum_{i=1}^{n} (x_i - \mu)^2 \cdot p(x_i)
    • 对于连续随机变量 XX 的方差,若其概率密度函数为 f(x)f(x),方差公式为:
    Var(X)=(xμ)2f(x)dx\mathrm{Var}(X) = \int_{-\infty}^{\infty} (x - \mu)^2 \cdot f(x) \, dx

    其中,μ=E(X)\mu = E(X) 是随机变量 XX 的期望值。

  • 加权平均

    • 期望的公式乍一看并不像“普通的平均值公式”,但它蕴含了类似的思想。期望的“平均概念”体现在它是所有可能结果的加权平均值:
    E(X)=i=1nxip(xi)E(X) = \sum_{i=1}^{n} x_i \cdot p(x_i)
    • 这个公式与普通平均值的不同在于,它考虑了每个结果的概率权重。普通的平均值是各数值直接相加除以总个数,而期望则是各结果乘以出现概率,再求和。
    • 假设我们扔一个不均匀的骰子,其中1-6的概率分别为0.1、0.1、0.2、0.2、0.2、0.2。这个不均匀骰子的期望就是:E(X)=1×0.1+2×0.1+3×0.2+4×0.2+5×0.2+6×0.2=4.2E(X)=1×0.1+2×0.1+3×0.2+4×0.2+5×0.2+6×0.2=4.2
    • 这个期望值4.2是所有结果的概率加权平均,反映了在长期中我们对结果的“平均期待”
    • 通过概率权重,期望可以适用于更一般的场景,比直接的算术平均更灵活,同时依然保留了“平均”的核心思想。

总结

  • 我们可以从概率分布中采样。
  • 我们可以使用联合分布、条件分布、Bayes定理、边缘化和独立性假设来分析多个随机变量。
  • 期望和方差为概率分布的关键特征的概括提供了实用的度量形式。