在这里插入图片描述

学习目标:理解概率的本质,掌握条件概率和贝叶斯定理
预计时间: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%

关键洞察

  1. 假阳性的绝对数量很大

    • 虽然假阳性率只有5%
    • 但健康人基数大(990人)
    • 所以假阳性有49.5人
  2. 真阳性的绝对数量很小

    • 虽然真阳性率有95%
    • 但患病人基数小(10人)
    • 所以真阳性只有9.5人
  3. 基础概率(先验概率)很重要

    • 不能只看测试准确率
    • 必须考虑疾病的患病率
    • 患病率越低,阳性结果的可信度越低

实际应用

  • 医疗诊断:阳性结果需要进一步确认
  • 垃圾邮件过滤:不能只看单个特征
  • 安全检测:低概率事件的检测需要多重验证
  • 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能够处理不确定性! 🎲✨

Logo

有“AI”的1024 = 2048,欢迎大家加入2048 AI社区

更多推荐