跳到主要内容

概率基础:不确定性的度量

概率分布与贝叶斯更新图

为什么学概率?

AI 本质上就是在"不确定性"中做决策。模型输出的不是"这张图一定是猫",而是"这张图有 95% 的概率是猫"。概率论就是处理不确定性的数学工具。

学习目标

  • 理解概率的两种理解方式(频率 vs 信念)
  • 掌握条件概率和联合概率
  • 用经典案例理解贝叶斯定理
  • 用 Python 模拟验证概率公式

历史背景:贝叶斯法则从哪里来?

这一节最值得知道的历史节点是:

年份节点它最重要地解决了什么
1763Bayes' Theorem(后由 Price 整理发表)奠定了“有了新证据以后,怎样更新判断”这条概率推断主线

对新人来说,最值得先记的不是原始论文细节,而是:

贝叶斯法则最大的价值,不是一个公式本身,而是它把“先验判断 + 新证据 = 更新后的判断”这件事说清楚了。

这也是为什么后面机器学习里:

  • 垃圾邮件判断
  • 医疗检测
  • 朴素贝叶斯

都会反复回到这条更新逻辑上。

为什么贝叶斯会一直让很多初学者觉得“很有意思”?

因为它不像很多公式那样只是在算数,
它更像是在回答一个很像现实生活的问题:

  • 我原来怎么判断
  • 新证据来了以后,我该不该改主意

这件事特别容易让人产生代入感。
比如医学检测、垃圾邮件判断、风控、推荐系统,
本质上都不是“绝对知道答案”,而是在做:

  • 一边看证据
  • 一边更新把握

所以贝叶斯法则之所以一直被人记住,
往往不是因为它“优雅”,
而是因为它特别像真实世界里人做判断的方式。

这件事为什么会让后人一直记住?

因为它第一次非常清楚地告诉人们:

  • 推理不是“有了结论就结束”
  • 推理其实可以随着证据不断更新

这听起来今天很自然,但在历史上它很重要。
你可以把贝叶斯法则想成一句特别朴素、但影响很深的话:

我原来怎么想不重要,重要的是拿到新证据后,我愿不愿意更新判断。

这也是为什么它不只是一条数学公式,
而更像一整种看待不确定世界的方式。

先说一个很重要的学习预期

这一节不会把概率论所有内容都讲完。
它更现实的目标是:

  • 先让你知道“概率不是玄学,而是在描述不确定”
  • 先让你知道“有了新信息以后,判断会更新”
  • 先让你知道“模型输出概率”背后到底在说什么

所以你这一节最重要的目标,不是把每个公式背到滚瓜烂熟,
而是先把:

  • 事件
  • 条件
  • 更新

这三件事看顺。


先建立一张地图

这一节最好先把它放回整章里理解:

这节真正要学的,不只是几个公式,而是:

  • 世界里很多判断都不是 0 或 1
  • 有了新证据后,我们的判断会更新
  • 这正是 AI 模型输出概率时的基本思路

一、概率是什么?

1.1 两种理解方式

在 AI 中,两种理解都用到:

  • 训练模型时:用频率学派的方法(大量数据统计规律)
  • 模型推断时:用贝叶斯的方法(根据观测更新信念)

1.1.1 一个更适合新人的类比

可以先把概率想成两种不同语境下的“把握程度”:

  • 频率学派:像反复做实验后的统计结论
  • 贝叶斯学派:像拿到证据后对一件事的主观把握更新

1.2 用 Python 体验"频率即概率"

import numpy as np
import matplotlib.pyplot as plt

plt.rcParams['font.sans-serif'] = ['Arial Unicode MS']
plt.rcParams['axes.unicode_minus'] = False

# 模拟抛硬币
np.random.seed(42)
n_flips = 10000
results = np.random.choice(['正面', '反面'], size=n_flips)

# 随着抛的次数增加,正面比例趋近 0.5
cumulative_ratio = np.cumsum(results == '正面') / np.arange(1, n_flips + 1)

plt.figure(figsize=(10, 5))
plt.plot(cumulative_ratio, color='steelblue', linewidth=1)
plt.axhline(y=0.5, color='red', linestyle='--', label='理论概率 0.5')
plt.xlabel('抛掷次数')
plt.ylabel('正面出现的比例')
plt.title('大数定律:抛的次数越多,比例越接近真实概率')
plt.legend()
plt.xscale('log')
plt.grid(True, alpha=0.3)
plt.show()

大数定律:实验次数越多,频率越接近真实概率。这就是为什么深度学习需要"大数据"。


二、条件概率——"在已知某些信息时"

2.1 直觉理解

条件概率 P(A|B) = 在已知 B 发生的前提下,A 发生的概率。

2.1.1 为什么条件概率这么像 AI 的思考方式?

因为现实里的判断几乎总是在“有上下文”的情况下发生。

也就是说,条件概率最重要的不是符号,而是这句话:

一旦知道了更多信息,原来的判断就应该更新。

生活例子
  • P(迟到 | 堵车) = 在堵车的情况下迟到的概率(远高于平时)
  • P(及格 | 认真复习) = 认真复习了及格的概率(也远高于平时)
  • P(是垃圾邮件 | 包含"免费") = 包含"免费"这个词的邮件是垃圾邮件的概率

2.2 公式与计算

P(A|B) = P(A 且 B) / P(B)

用一个直观的例子:

# 一个班 100 个学生
# 60 人喜欢数学,50 人喜欢编程,30 人两者都喜欢

n_total = 100
n_math = 60
n_code = 50
n_both = 30

# P(喜欢编程 | 喜欢数学) = P(两者都喜欢) / P(喜欢数学)
p_code_given_math = n_both / n_math
print(f"喜欢数学的人中,也喜欢编程的比例: {p_code_given_math:.1%}") # 50%

# P(喜欢数学 | 喜欢编程)
p_math_given_code = n_both / n_code
print(f"喜欢编程的人中,也喜欢数学的比例: {p_math_given_code:.1%}") # 60%

注意:P(A|B) 和 P(B|A) 通常不相等!

2.2.1 这是新人最容易踩的坑之一

很多人第一次学到这里,会下意识把:

  • “在喜欢数学的人里,有多少人喜欢编程”

  • “在喜欢编程的人里,有多少人喜欢数学”

混成一件事。
但它们问的分母不一样,所以本质上就是两个不同问题。

2.3 联合概率与边缘概率

# 用 NumPy 模拟数据
np.random.seed(42)
n = 10000

# 天气:晴(0.7) / 雨(0.3)
weather = np.random.choice(['晴', '雨'], n, p=[0.7, 0.3])

# 带伞概率取决于天气
umbrella = np.where(
weather == '雨',
np.random.choice(['带', '不带'], n, p=[0.8, 0.2]), # 下雨时 80% 会带伞
np.random.choice(['带', '不带'], n, p=[0.1, 0.9]) # 晴天时 10% 会带伞
)

# 联合概率表
import pandas as pd
df = pd.DataFrame({'天气': weather, '带伞': umbrella})
joint = pd.crosstab(df['天气'], df['带伞'], normalize=True)
print("联合概率表:")
print(joint.round(3))
print(f"\n边缘概率 P(雨): {(weather == '雨').mean():.3f}")
print(f"边缘概率 P(带伞): {(umbrella == '带').mean():.3f}")
带伞不带合计(边缘概率)
0.070.630.70
0.240.060.30
合计0.310.691.00

三、贝叶斯定理——AI 最重要的概率公式

3.1 引入:医院检查的故事

一种罕见疾病的发病率是 0.1%(1000 人中 1 人有病)。医院有一个检测方法:

  • 如果你有病,检测出阳性的概率是 99%(灵敏度)
  • 如果你没病,检测出阳性的概率是 5%(假阳率)

问题:如果你检测出了阳性,你真正有病的概率是多少?

很多人直觉会说"99%"——但答案会让你大吃一惊。

3.2 贝叶斯公式

P(有病 | 阳性) = P(阳性 | 有病) × P(有病) / P(阳性)

# 已知条件
p_disease = 0.001 # 先验概率:发病率 0.1%
p_positive_if_disease = 0.99 # 有病 → 阳性的概率
p_positive_if_healthy = 0.05 # 没病 → 阳性的概率(假阳率)

# P(阳性) = P(阳性|有病)×P(有病) + P(阳性|没病)×P(没病)
p_positive = (p_positive_if_disease * p_disease +
p_positive_if_healthy * (1 - p_disease))
print(f"P(阳性): {p_positive:.4f}")

# 贝叶斯公式
p_disease_if_positive = (p_positive_if_disease * p_disease) / p_positive
print(f"P(有病|阳性): {p_disease_if_positive:.4f}") # ≈ 0.0194
print(f"约等于 {p_disease_if_positive:.1%}") # ≈ 1.9%

结果:只有约 2%! 即使检测阳性,你有病的概率也只有 2%。

3.3 为什么这么低?

因为发病率太低了(0.1%),绝大多数阳性结果其实是假阳性。

# 用 10000 人模拟
n_people = 10000
n_sick = int(n_people * p_disease) # 10 人有病
n_healthy = n_people - n_sick # 9990 人没病

true_positive = n_sick * p_positive_if_disease # 有病且检测阳性: ≈ 10
false_positive = n_healthy * p_positive_if_healthy # 没病但检测阳性: ≈ 500

total_positive = true_positive + false_positive

print(f"10000 人中:")
print(f" 有病的人: {n_sick}")
print(f" 检测阳性的人: {total_positive:.0f}")
print(f" 其中真阳性: {true_positive:.0f}")
print(f" 其中假阳性: {false_positive:.0f}")
print(f" 阳性中真有病的比例: {true_positive/total_positive:.1%}")

3.4 贝叶斯定理的核心思想

后验 = 先验 × 似然 / 归一化因子

这就是贝叶斯的核心:不断用新证据更新你的信念

3.5 用模拟验证贝叶斯定理

# 蒙特卡洛模拟
np.random.seed(42)
n_sim = 1_000_000

# 1. 每个人是否有病
has_disease = np.random.random(n_sim) < p_disease

# 2. 每个人的检测结果
test_positive = np.where(
has_disease,
np.random.random(n_sim) < p_positive_if_disease, # 有病
np.random.random(n_sim) < p_positive_if_healthy # 没病
)

# 3. 在检测阳性的人中,有病的比例
positive_people = test_positive.sum()
positive_and_sick = (test_positive & has_disease).sum()

simulated_probability = positive_and_sick / positive_people
print(f"模拟结果 P(有病|阳性): {simulated_probability:.4f}")
print(f"公式计算: {p_disease_if_positive:.4f}")
print(f"两者差距: {abs(simulated_probability - p_disease_if_positive):.6f}")

四、贝叶斯定理在 AI 中的应用

4.1 朴素贝叶斯分类器

垃圾邮件过滤就是贝叶斯定理的经典应用:

# 简化的垃圾邮件分类
# P(垃圾邮件 | 包含"免费") = P(包含"免费"|垃圾邮件) × P(垃圾邮件) / P(包含"免费")

p_spam = 0.3 # 30% 的邮件是垃圾邮件
p_free_given_spam = 0.8 # 垃圾邮件中 80% 包含"免费"
p_free_given_ham = 0.05 # 正常邮件中 5% 包含"免费"

# P(包含"免费")
p_free = p_free_given_spam * p_spam + p_free_given_ham * (1 - p_spam)

# 贝叶斯
p_spam_given_free = p_free_given_spam * p_spam / p_free
print(f"包含'免费'的邮件是垃圾邮件的概率: {p_spam_given_free:.1%}")
# ≈ 87.3%

4.2 更多 AI 应用

应用先验似然后验
垃圾邮件过滤邮件是垃圾邮件的概率垃圾邮件包含某词的概率给定词后是垃圾邮件的概率
医学诊断疾病的发病率有病时检测阳性的概率阳性后真有病的概率
推荐系统用户喜欢某类型的概率喜欢该类型的人看某电影的概率用户会看这部电影的概率
语言模型某个词出现的概率前文给定后该词出现的概率最可能的下一个词

五、独立性——简化计算的利器

5.1 什么是独立?

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

P(A 且 B) = P(A) × P(B) (仅当 A、B 独立时)

# 抛两次硬币——两次是独立的
p_head = 0.5

# 两次都是正面
p_both_heads = p_head * p_head
print(f"两次都正面: {p_both_heads}") # 0.25

# 模拟验证
n = 100000
coin1 = np.random.random(n) < 0.5
coin2 = np.random.random(n) < 0.5
both = (coin1 & coin2).mean()
print(f"模拟结果: {both:.4f}") # ≈ 0.25

5.2 AI 中的独立性假设

朴素贝叶斯之所以叫"朴素",就是因为它假设所有特征独立(虽然实际中往往不独立,但效果依然不错)。

# 朴素贝叶斯:假设各个词独立出现
# P(垃圾|"免费","中奖","点击") ∝ P(垃圾) × P("免费"|垃圾) × P("中奖"|垃圾) × P("点击"|垃圾)

p_spam = 0.3
words = {
"免费": (0.8, 0.05), # (P(词|垃圾), P(词|正常))
"中奖": (0.6, 0.01),
"点击": (0.7, 0.1),
}

# 计算分子
score_spam = p_spam
score_ham = 1 - p_spam

for word, (p_word_spam, p_word_ham) in words.items():
score_spam *= p_word_spam
score_ham *= p_word_ham

# 归一化
p_spam_given_words = score_spam / (score_spam + score_ham)
print(f"邮件包含 '免费'+'中奖'+'点击' 是垃圾邮件的概率: {p_spam_given_words:.1%}")

学到这里,下一节该带着什么问题走?

看完概率基础以后,最值得带去下一节的问题是:

  1. 如果一次事件可以用概率描述,那很多次随机结果整体会长什么样?
  2. 为什么有些现象总像钟形曲线,有些现象却更像计数分布?
  3. 模型里的噪声、初始化和误差,为什么总爱和某些分布绑在一起?

这三个问题,正好会把你自然带到:

连接后续
  • 下一节:概率分布——数据背后的规律
  • 5 机器学习入门到实战:朴素贝叶斯分类器直接基于贝叶斯定理
  • 5 机器学习入门到实战:逻辑回归的输出就是条件概率 P(y=1|x)
  • 7 大模型原理、Prompt 与微调:大语言模型生成下一个 token 的概率分布

小结

概念直觉公式/代码
概率不确定性的度量(0~1)np.random.random() < p
条件概率已知 B 发生时 A 的概率P(A|B) = P(A且B) / P(B)
联合概率A 和 B 同时发生的概率pd.crosstab(normalize=True)
贝叶斯定理用证据更新信念后验 = 先验 × 似然 / 归一化
独立性互不影响P(A且B) = P(A) × P(B)

这节最该带走什么

  • 概率是在描述不确定,不是在假装绝对确定
  • 条件概率最重要的直觉是“信息一变,判断就该变”
  • 贝叶斯最值得先记的是“先验 + 证据 -> 更新后的判断”
  • 这就是为什么 AI 里的很多输出天然是概率,而不是绝对结论

动手练习

练习 1:条件概率

一副 52 张扑克牌,随机抽一张:

  1. P(红心) = ?
  2. P(红心 | 红色) = ?(已知是红色牌)
  3. P(A | 红心) = ?(已知是红心)

用 Python 模拟 100000 次验证。

练习 2:贝叶斯更新

一个工厂有 A、B 两条生产线,A 生产 60% 的产品,B 生产 40%。A 的次品率是 2%,B 的次品率是 5%。

如果随机取一个产品发现是次品,它来自 B 生产线的概率是多少?

练习 3:模拟贝叶斯定理

修改疾病检测的例子,改为发病率 1%(而不是 0.1%),看看阳性后有病的概率变成多少。用模拟和公式两种方法验证。