运气也能计算?贝叶斯公式与概率基础,打开 AI 统计学的大门
·

学习目标:理解概率的本质,掌握条件概率和贝叶斯定理
预计时间:15-20分钟
前置知识:初中数学基础即可
📋 本篇内容
概率基础 → 条件概率 → 贝叶斯定理
🎯 1. 概率:不确定性的数学
1.1 什么是概率?
生活类比:概率就是"某件事发生的可能性大小"
import numpy as np
import matplotlib.pyplot as plt
# 例子1:抛硬币
# 概率 = 想要的结果数 / 所有可能的结果数
coin_outcomes = ['正面', '反面']
prob_heads = 1 / 2 # 50%
print(f"抛硬币正面朝上的概率: {prob_heads}")
# 例子2:掷骰子
dice_outcomes = [1, 2, 3, 4, 5, 6]
prob_six = 1 / 6 # 约16.67%
print(f"掷骰子得到6的概率: {prob_six:.2%}")
# 例子3:模拟抛硬币1000次
np.random.seed(42)
flips = np.random.choice(['正面', '反面'], size=1000)
heads_count = np.sum(flips == '正面')
print(f"1000次中正面出现: {heads_count}次 ({heads_count/1000:.1%})")
1.2 概率的基本规则
import numpy as np
# 规则1:概率范围 [0, 1]
# 0 = 不可能发生
# 1 = 一定发生
# 0.5 = 50%可能性
# 规则2:互斥事件的概率相加
# 例子:掷骰子得到1或2的概率
prob_1 = 1/6
prob_2 = 1/6
prob_1_or_2 = prob_1 + prob_2 # 2/6 = 1/3
print(f"得到1或2的概率: {prob_1_or_2:.2%}")
# 规则3:独立事件的概率相乘
# 例子:连续两次抛硬币都是正面
prob_heads = 0.5
prob_two_heads = prob_heads * prob_heads # 0.25
print(f"连续两次正面的概率: {prob_two_heads:.2%}")
# 规则4:补集概率
# P(不发生) = 1 - P(发生)
prob_rain = 0.3 # 下雨概率30%
prob_no_rain = 1 - prob_rain # 不下雨70%
print(f"不下雨的概率: {prob_no_rain:.2%}")
🔄 2. 条件概率
2.1 什么是条件概率?
生活类比:看天气预报决定是否带伞
场景1:不看天气预报
- 你只知道"这个月下雨的概率是30%"
- 所以你觉得今天下雨的概率是30%
场景2:看了天气预报
- 天气预报说"今天有乌云"
- 你知道"有乌云时,80%会下雨"
- 现在你觉得今天下雨的概率变成了80%!
这就是条件概率:
- P(下雨) = 30%(不知道任何信息)
- P(下雨|有乌云) = 80%(知道有乌云后)
"|"符号的意思:在…的条件下
- P(A|B) 读作:“在B发生的条件下,A发生的概率”
生活例子:
看病诊断
- P(感冒) = 20%(这个季节感冒的人占20%)
- P(发烧|感冒) = 80%(感冒的人中80%会发烧)
- 如果你发烧了,医生会更倾向于判断你感冒了
2.2 条件概率的计算
import numpy as np
# 例子:邮件分类(垃圾邮件过滤)
#
# 已知信息:
# - P(垃圾邮件) = 30%(收到的邮件中,30%是垃圾邮件)
# - P(包含"中奖"|垃圾邮件) = 80%(垃圾邮件中,80%包含"中奖")
# - P(包含"中奖"|正常邮件) = 5%(正常邮件中,只有5%包含"中奖")
#
# 问题:收到一封包含"中奖"的邮件,它是垃圾邮件的概率是多少?
p_spam = 0.3 # P(垃圾邮件) = 30%,先验概率(根据历史数据统计)
p_normal = 0.7 # P(正常邮件) = 70%,先验概率
p_word_given_spam = 0.8 # P(包含"中奖"|垃圾邮件) = 80%,似然概率
p_word_given_normal = 0.05 # P(包含"中奖"|正常邮件) = 5%,似然概率
# 使用全概率公式计算:P(包含"中奖")
# P(包含"中奖") = P(垃圾)*P(词|垃圾) + P(正常)*P(词|正常)
p_word = p_spam * p_word_given_spam + p_normal * p_word_given_normal
print(f"包含'中奖'的邮件占比: {p_word:.2%}")
# 计算:0.3 × 0.8 + 0.7 × 0.05 = 0.24 + 0.035 = 0.275 = 27.5%
# 使用贝叶斯公式计算:P(垃圾|包含"中奖")
# P(垃圾|包含"中奖") = P(垃圾)*P(词|垃圾) / P(包含"中奖")
p_spam_given_word = (p_spam * p_word_given_spam) / p_word
print(f"包含'中奖'的邮件是垃圾邮件的概率: {p_spam_given_word:.2%}")
# 计算:(0.3 × 0.8) / 0.275 = 0.24 / 0.275 ≈ 0.873 = 87.3%
💡 理解这些概率:
1. 先验概率(Prior):根据历史数据得出
- P(垃圾邮件) = 30%:收到的邮件中,30%是垃圾邮件
- P(正常邮件) = 70%:收到的邮件中,70%是正常邮件
2. 似然概率(Likelihood):特征在不同类别中出现的概率
- P(“中奖”|垃圾邮件) = 80%:垃圾邮件中,80%包含"中奖"
- P(“中奖”|正常邮件) = 5%:正常邮件中,只有5%包含"中奖"
3. 后验概率(Posterior):根据新证据更新后的概率
- P(垃圾邮件|“中奖”) = 87.3%:看到"中奖"后,是垃圾邮件的概率
结论:虽然只有30%的邮件是垃圾邮件,但如果邮件包含"中奖",那么它是垃圾邮件的概率就上升到87.3%!
🧠 3. 贝叶斯定理:AI的核心思想
3.1 贝叶斯定理的直观理解
生活类比:侦探破案
场景:你的手机不见了
初始判断(先验概率):
- 可能在家里:70%
- 可能在办公室:20%
- 可能丢了:10%
新证据出现:你打电话,听到铃声从沙发下传来
更新判断(后验概率):
- 在家里:99%(几乎确定!)
- 在办公室:0%
- 丢了:1%
这就是贝叶斯定理:
- 先有一个初步判断(先验)
- 看到新证据(似然)
- 更新判断(后验)
公式表达:
P(在家|听到铃声) = P(听到铃声|在家) × P(在家) / P(听到铃声) = 100% × 70% / 70% ≈ 99%
3.2 经典案例:医疗诊断
import numpy as np
# 经典例子:医疗诊断
# 已知:
# - 某疾病的患病率:1%
# - 测试的准确率:95%(有病测出有病,无病测出无病)
# 问题:测试结果为阳性,真的有病的概率是多少?
# 很多人会说95%,但实际上...
p_disease = 0.01 # 患病率1%
p_healthy = 0.99 # 健康率99%
p_positive_given_disease = 0.95 # 有病测出阳性
p_positive_given_healthy = 0.05 # 无病测出阳性(假阳性)
# 贝叶斯公式:
# P(有病|阳性) = P(阳性|有病) * P(有病) / P(阳性)
# 计算P(阳性)
p_positive = (p_positive_given_disease * p_disease +
p_positive_given_healthy * p_healthy)
# 计算P(有病|阳性)
p_disease_given_positive = (p_positive_given_disease * p_disease) / p_positive
print(f"测试阳性时真的有病的概率: {p_disease_given_positive:.2%}")
print("惊讶吗?只有16%!因为患病率太低了。")
这个例子说明了什么?
这是贝叶斯定理最经典的反直觉案例,揭示了一个重要道理:
核心发现:
- 测试准确率95%,但测试阳性时真的有病的概率只有16%!
- 为什么?因为基础患病率太低(只有1%)
直观理解:
假设有1000个人去检测:
1000人中:
├─ 10人真的有病(1%)
│ └─ 测试阳性:9.5人(95%准确)
│ └─ 测试阴性:0.5人(5%误差)
│
└─ 990人健康(99%)
└─ 测试阴性:940.5人(95%准确)
└─ 测试阳性:49.5人(5%假阳性)← 关键!
测试阳性的总人数 = 9.5 + 49.5 = 59人
其中真的有病的 = 9.5人
真有病的概率 = 9.5 / 59 ≈ 16%
关键洞察:
-
假阳性的绝对数量很大
- 虽然假阳性率只有5%
- 但健康人基数大(990人)
- 所以假阳性有49.5人
-
真阳性的绝对数量很小
- 虽然真阳性率有95%
- 但患病人基数小(10人)
- 所以真阳性只有9.5人
-
基础概率(先验概率)很重要
- 不能只看测试准确率
- 必须考虑疾病的患病率
- 患病率越低,阳性结果的可信度越低
实际应用:
- 医疗诊断:阳性结果需要进一步确认
- 垃圾邮件过滤:不能只看单个特征
- 安全检测:低概率事件的检测需要多重验证
- AI模型评估:准确率高不等于实际效果好
教训:不要被"95%准确率"迷惑,要考虑实际场景中的基础概率!
这就是为什么医生看到阳性结果后,通常会要求做进一步检查的原因。
3.3 朴素贝叶斯分类器
import numpy as np
from collections import defaultdict
# 例子:垃圾邮件分类
# 训练数据
emails = [
("中奖 免费 点击", "spam"),
("会议 明天 讨论", "normal"),
("免费 领取 奖品", "spam"),
("项目 进度 更新", "normal"),
("恭喜 中奖 领取", "spam"),
]
# 统计词频
word_counts = defaultdict(lambda: {"spam": 0, "normal": 0})
class_counts = {"spam": 0, "normal": 0}
for text, label in emails:
class_counts[label] += 1
for word in text.split():
word_counts[word][label] += 1
# 计算概率
total = len(emails)
p_spam = class_counts["spam"] / total
p_normal = class_counts["normal"] / total
print(f"P(垃圾邮件) = {p_spam:.2f}")
print(f"P(正常邮件) = {p_normal:.2f}")
# 预测新邮件
def predict(text):
words = text.split()
# 计算 P(垃圾|词1,词2,...) ∝ P(垃圾) * P(词1|垃圾) * P(词2|垃圾) * ...
score_spam = p_spam
score_normal = p_normal
for word in words:
if word in word_counts:
# 使用拉普拉斯平滑
score_spam *= (word_counts[word]["spam"] + 1) / (class_counts["spam"] + 2)
score_normal *= (word_counts[word]["normal"] + 1) / (class_counts["normal"] + 2)
return "spam" if score_spam > score_normal else "normal"
# 测试
test_email = "免费 中奖"
result = predict(test_email)
print(f"\n'{test_email}' 被分类为: {result}")
🎯 总结
核心概念
- ✅ 概率是不确定性的度量(0到1之间)
- ✅ 条件概率:在某个条件下的概率
- ✅ 贝叶斯定理:根据新证据更新概率
- ✅ 先验概率很重要,不能忽视
概率让AI能够处理不确定性! 🎲✨
更多推荐

所有评论(0)