机器学习的核心:预测
简单来说,机器学习的核心任务就是预测。通过建立模型,我们可以在不确定的情况下尽量精准地推测出未来的情况。例如:
- 医疗领域:根据病人的病史预测他们在下一年心脏病发作的概率。
- 异常检测:在飞机喷气发动机的监控中评估一组读数属于正常运行情况的概率。
- 强化学习:希望智能体在一个环境中能以高概率选择获得高奖励的行为。
- 推荐系统:在在线书店中,估计用户购买特定图书的概率。
为了达到这些预测目标,我们需要运用概率论。概率理论是一门专门研究不确定性事件的学科,通过它,我们可以更系统地表达各种可能性。然而,这里我们只介绍基础知识,帮助你开始理解和构建简单的机器学习模型。
考虑一个经典的机器学习任务:图像分类。比如,通过照片判断一张图是猫还是狗。人类在高分辨率图像中很容易辨认,但低分辨率的图片却让任务变得困难。在某种低分辨率下(如2x2像素),我们区分猫和狗几乎只能凭运气。这时,概率给了我们一个衡量确定性的工具。如果我们完全确定图像是一只猫,概率就是1;如果我们毫无头绪,我们可以给“猫”和“狗”各赋0.5的概率;如果较偏向认为是猫,但不完全确定,我们可能会赋0.7给“猫”。
再看另一个例子:天气预报。假设我们通过分析过去的数据,预测出明天北京下雨的概率为0.5。这类问题也是预测,但与图像分类稍有不同——天气是一种随机现象,可能受多种因素影响。
这两个例子展示了概率的不同应用方式,它既可以用于帮助我们在确定或不确定的情况下进行推测,也适用于多种机器学习任务。
一、基本概率论
概率(probability) 可以被看作是将集合映射到真实值的函数。在掷骰子的实验中,我们有一个样本空间(sample space),即所有可能的结果。在掷一个公平的六面骰子时,样本空间为{1, 2, 3, 4, 5, 6}。假设我们想知道掷出1的概率。对于一个公平的骰子,结果是均匀分布的,因此每个结果出现的概率都是
。
要验证骰子是否公平,我们需要多次投掷并记录结果。对于每个数字,我们可以计算它出现的次数并除以投掷的总次数,以此作为该事件概率的估计值。根据大数定律,随着投掷次数的增加,这个估计值会越来越接近真实的概率。
以下是相应的代码示例,用于模拟投掷骰子的过程:
在统计学中,我们把从概率分布中抽取样本的过程称为抽样(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])
因为我们是从一个公平的骰子中生成的数据,我们知道每个结果都有真实的概率, 大约是 ,所以上面输出的估计值看起来不错。
我们也可以看到这些概率如何随着时间的推移收敛到真实概率。 让我们进行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()
每条实线对应于骰子的6个值中的一个,并给出骰子在每组实验后出现值的估计概率。 当我们通过更多的实验获得更多的数据时,这6条实体曲线向真实概率收敛。
1.1 概率论公理
概率论的三条公理为我们提供了计算概率的基本规则:
- 非负性: 任何事件的概率都是非负的,即 。
- 规范性: 确定事件(必然发生的事件)的概率为1,即 。
- 可加性: 如果两个事件 和 互斥(即它们不能同时发生),那么它们的联合概率是单独发生的概率之和,即 。
这些公理帮助我们确定事件发生的可能性。
1.2 随机变量
随机变量是一个数值表示随机现象的变量。例如,抛一枚硬币,我们可以用0表示正面,用1表示反面。随机变量分为离散随机变量(有有限可能值)和连续随机变量(可以取无限多的值)。理解随机变量帮助我们从数学上描述事件的结果。
二、处理多个随机变量
当我们处理多个随机变量时,概率的计算变得更为复杂。以下是几个重要的概念:
2.1 联合概率
联合概率描述了两个事件同时发生的概率。例如,设事件A表示“今天下雨”,事件B表示“今天打雷”,则事件“A且B发生”的概率就是A和B的联合概率,用 表示。
2.2 条件概率
条件概率表示在已知一个事件发生的情况下,另一个事件发生的概率。设事件B已经发生,事件A发生的概率则用 表示。条件概率公式为:
2.3 贝叶斯定理
贝叶斯定理是一种通过已知信息更新概率的工具,公式为:
贝叶斯定理帮助我们从反向角度(如从结果推测原因)理解概率,在机器学习中用于分类、决策等任务。
2.4 边际化
边际化用于计算某一个事件的总体概率,而不关心其他事件的具体情况。例如,设有事件A和B,则边际概率 可通过联合概率加总得到。
2.5 独立性
两个事件A和B独立,意味着一个事件的发生不影响另一个事件的概率。即:
独立性在概率计算中极为重要,它简化了许多复杂的计算。
2.6 应用
概率理论广泛应用于机器学习中的模型选择、预测、分类等。理解概率可以帮助我们更准确地预测事件发生的可能性,提高模型的准确性。
医疗诊断 - 贝叶斯定理
问题:假设一个疾病在总体人群中的发病率为1%,测试准确率为95%。如果测试结果为阳性,患者实际患病的概率是多少?
分析:
事件患病记为 ,概率为1%;事件阳性记为 。
使用贝叶斯公式:
求 :
其中:
-
,即测试准确率
-
,即发病率
-
-
三、期望和方差
在处理概率时,期望和方差是两个重要的统计量。
-
期望(平均值): 期望就是你可以期待的 “平均结果” 。假如你每天上学路上走10分钟,偶尔走慢些会花15分钟,有时走快些只花5分钟。那么你走这一条路的期望时间可能接近10分钟,代表你整体上的平均表现。期望帮助我们在面对不确定性的时候抓住“整体趋势”,比如平均下来这件事大约的结果会是什么。
- 如果对于一个离散随机变量 和它的取值 及其概率 ,期望值 可以表示为:
- 对于连续随机变量 的情况,若概率密度函数为 ,则期望值 表示为:
-
方差: 方差反映数据的 “波动情况” 或 “离散程度” 。它告诉我们数据是集中在期望附近,还是分散得很开。如果每天上学的时间总是10分钟,那方差几乎为0,因为波动很小;但如果某天走路花5分钟,某天15分钟,那么方差就比较大,表示时间上有波动。方差帮助我们理解事物的稳定性或者波动性,能够反映在长期中,事情是“相对稳定”还是“时常变化”的。
- 对于离散随机变量 的方差 ,计算公式是:
- 对于连续随机变量 的方差,若其概率密度函数为 ,方差公式为:
其中, 是随机变量 的期望值。
-
加权平均
- 期望的公式乍一看并不像“普通的平均值公式”,但它蕴含了类似的思想。期望的“平均概念”体现在它是所有可能结果的加权平均值:
- 这个公式与普通平均值的不同在于,它考虑了每个结果的概率权重。普通的平均值是各数值直接相加除以总个数,而期望则是各结果乘以出现概率,再求和。
- 假设我们扔一个不均匀的骰子,其中1-6的概率分别为0.1、0.1、0.2、0.2、0.2、0.2。这个不均匀骰子的期望就是:
- 这个期望值4.2是所有结果的概率加权平均,反映了在长期中我们对结果的“平均期待”。
- 通过概率权重,期望可以适用于更一般的场景,比直接的算术平均更灵活,同时依然保留了“平均”的核心思想。
总结
- 我们可以从概率分布中采样。
- 我们可以使用联合分布、条件分布、Bayes定理、边缘化和独立性假设来分析多个随机变量。
- 期望和方差为概率分布的关键特征的概括提供了实用的度量形式。