一、贝叶斯理论基础
1. 贝叶斯思想的核心
贝叶斯算法由 18 世纪英国数学家托马斯・贝叶斯提出,其核心是解决 “逆概” 问题 —— 区别于 “正向概率” 已知条件求结果概率的思路,逆概是通过观测到的结果,反推导致该结果的原因概率。
比如在日常生活中,“正向概率” 类似 “已知袋子里有 10 个白球和 5 个黑球,摸出黑球的概率是多少”;而 “逆概” 则是 “闭着眼睛摸出 3 个黑球和 2 个白球,推测袋子里黑白球的比例大概是多少”,这也是贝叶斯方法的核心应用场景。
2. 贝叶斯公式的逻辑理解
贝叶斯公式是算法的数学核心,虽然不用公式表达,但可以通过逻辑拆解理解:我们想知道 “在观测到结果 B 的情况下,原因 A 发生的概率”,这个概率取决于三个关键部分 —— 原因 A 本身发生的概率(先验概率)、在原因 A 发生时结果 B 出现的概率(条件概率),以及结果 B 整体发生的总概率(证据概率)。
在实际对比不同原因的可能性时,结果 B 的总概率往往是固定的,所以可以忽略这部分,只通过 “先验概率 × 条件概率” 的大小来判断哪个原因更可能。
3. 经典实例加深理解
(1)学生性别与穿着的推断
假设某学校男生占 60%、女生占 40%,且男生全部穿长裤,女生一半穿长裤、一半穿裙子。当看到一个穿长裤的学生时,如何推断其是女生的概率?
首先,计算 “穿长裤” 这个结果的总可能性:既包括男生穿长裤的情况,也包括女生穿长裤的情况。男生穿长裤的比例是 60%×100%=60%,女生穿长裤的比例是 40%×50%=20%,所以穿长裤的总比例是 60%+20%=80%。
而 “穿长裤的女生” 占比是 20%,因此 “穿长裤的学生是女生” 的概率就是 20%÷80%=25%,这就是通过贝叶斯逻辑计算出的逆概结果。
(2)拼写纠正的应用
当用户输入一个不在字典里的错误单词(比如 “tlp”),需要推测其真实想输入的单词时,贝叶斯逻辑同样适用。
我们把用户输入的错误单词当作 “观测结果”,把可能的正确单词(比如 “top”“tip”)当作 “可能的原因”。判断哪个原因更合理,需要考虑两点:一是正确单词本身在日常使用中出现的频率(先验概率),比如 “top” 比 “tip” 更常用,所以 “top” 的先验概率更高;二是错误单词与正确单词的相似程度(条件概率),“tlp” 和 “top” 只相差一个字母,比和 “tip” 的差异更小,所以 “tlp 由 top 错误生成” 的条件概率更高。
综合这两点,就能推断出用户更可能想输入 “top”。
(3)垃圾邮件分类的逻辑
面对一封未知邮件,判断它是否为垃圾邮件,也可以用贝叶斯思路解决。
首先,“先验概率” 可以通过邮件库计算:比如收集 1000 封邮件,其中 300 封是垃圾邮件,那么 “邮件是垃圾邮件” 的先验概率就是 30%,“是正常邮件” 的先验概率是 70%。
接着,处理邮件内容这个 “观测结果”:邮件由多个单词组成,我们需要计算 “在垃圾邮件中出现这些单词的概率”(条件概率)。由于朴素贝叶斯假设 “单词之间相互独立”,所以不需要考虑单词的顺序,只需分别统计每个单词在垃圾邮件中出现的频率,再将这些频率相乘,就能得到整体的条件概率。
最后,对比 “垃圾邮件先验概率 × 垃圾邮件条件概率” 和 “正常邮件先验概率 × 正常邮件条件概率” 的大小,哪个结果更大,就将邮件归为哪一类。
二、三种核心朴素贝叶斯模型
朴素贝叶斯根据特征数据的类型不同,分为三种常用模型,每种模型的适用场景、参数特点和使用逻辑都有明显区别:
1. 多项式朴素贝叶斯(MultinomialNB)
这种模型主要适用于离散型数据,尤其是像文本这样需要统计 “特征出现次数” 的场景。比如在文本分类中,统计每篇文章里每个单词出现的次数,这些 “次数” 就是离散型特征,适合用多项式模型处理。
它的关键参数有三个:一是 “alpha”,作用是添加拉普拉斯平滑 —— 如果某个单词在某类文本中从未出现,直接计算会出现 “零概率”,导致结果偏差,alpha 设为 1.0(默认值)时会自动修正这种情况,设为 0 则不添加平滑;二是 “fit_prior”,默认是 True,表示计算时会考虑先验概率,如果设为 False,会假设所有类别的先验概率相同;三是 “class_prior”,可以手动设置每个类别的先验概率,默认是 None,此时模型会根据样本数据自动计算。
在 sklearn 中,只需通过 “from sklearn.naive_bayes import MultinomialNB” 就能导入模型,再用 “MultinomialNB ()” 初始化即可。
2. 高斯朴素贝叶斯(GaussianNB)
当特征是连续型数据(比如身高、体重、温度等具体数值)时,适合用高斯模型。因为连续型数据无法像离散数据那样统计 “出现次数”,高斯模型会假设特征服从正态分布(也就是常见的 “钟形曲线” 分布),通过计算数据在分布中的概率密度,来得到条件概率。
它的核心参数是 “priors”,作用是手动设置每个类别的先验概率,默认是 None,此时模型会用 “极大似然法”—— 也就是根据样本中各类别的占比,自动计算先验概率。
导入方式是 “from sklearn.naive_bayes import GaussianNB”,初始化时直接调用 “GaussianNB ()” 即可,参数设置相对简单。
3. 伯努利朴素贝叶斯(BernoulliNB)
这种模型针对的是二值离散型数据,也就是特征的取值只有 0 和 1 两种情况(比如 “某个单词在文章中是否出现”—— 出现记为 1,不出现记为 0)。它关注的是 “特征是否存在”,而不是 “特征出现多少次”,这是它和多项式模型的核心区别。
它的参数除了和多项式模型类似的 “alpha”“fit_prior”“class_prior” 外,还有一个关键参数 “binarize”:如果输入的特征不是二值数据,这个参数可以设定一个阈值,将特征转换为 0 和 1(比如设为 0,那么小于 0 的数记为 0,大于等于 0 的数记为 1);如果特征已经是二值化的数据,把 “binarize” 设为 None 即可,默认值是 0。
导入和初始化方式为 “from sklearn.naive_bayes import BernoulliNB” 和 “BernoulliNB ()”。
三、朴素贝叶斯的核心 API(基于 sklearn)
不管是哪种朴素贝叶斯模型,在 sklearn 中都有一套通用的 API,用于完成模型训练、预测和评估,具体功能如下:
fit(X, Y):这是模型训练的核心方法,需要传入两个参数 ——X 是特征数据(比如文本的单词次数矩阵、连续型的数值特征),Y 是对应的类别标签(比如文本的 “正面 / 负面”、邮件的 “垃圾 / 正常”)。调用这个方法后,模型会根据数据学习到特征和类别的关联规律。
predict(X):用于对新的特征数据 X 进行类别预测,输出的是每个样本对应的类别标签。比如训练好垃圾邮件分类模型后,传入一封新邮件的特征,调用这个方法就能得到 “垃圾邮件” 或 “正常邮件” 的预测结果。
predict_proba(X):和 predict 类似,但输出的不是具体类别,而是每个样本属于各个类别的概率值。比如预测某封邮件时,可能输出 “属于垃圾邮件的概率是 85%,属于正常邮件的概率是 15%”,概率值的总和为 1,能更直观地看到模型的判断依据。
predict_log_proba(X):功能和 predict_proba 类似,但输出的是概率的对数值。因为当多个概率相乘时,数值可能会非常小,容易出现 “计算下溢”(数值过小无法准确存储),取对数后可以避免这个问题,同时不影响不同类别概率的相对大小。
score(X, Y):用于评估模型的性能,需要传入测试集的特征 X 和对应的真实标签 Y,输出的是模型在测试集上的准确率(正确预测的样本数占总样本数的比例)。比如测试集有 100 个样本,模型预测对了 92 个,score 方法就会返回 0.92,表示准确率为 92%。
四、实践应用:手写数字识别(课堂练习)
基于 sklearn 提供的手写数字数据集,我们可以用朴素贝叶斯实现数字识别任务,具体步骤如下:
1. 导入所需工具和数据集
首先需要导入相关的库:高斯朴素贝叶斯模型(因为手写数字的特征是像素值,属于连续型数据)、手写数字数据集加载工具、数据集划分工具,以及准确率评估工具。
手写数字数据集(load_digits)包含了很多手写数字的图像数据,每个图像的像素值被整理成了特征,类别标签是 0-9 的数字,我们需要先加载这个数据集,把特征和标签分别提取出来 ——X 表示特征矩阵(每个样本对应一行像素值),Y 表示每个样本的真实数字标签。
2. 划分训练集和测试集
为了验证模型的泛化能力(对新数据的预测效果),需要将数据集分成两部分:训练集用于训练模型,测试集用于评估模型。通常会按照 “8:2” 或 “7:3” 的比例划分,这里以 8:2 为例,用 train_test_split 工具将 X 和 Y 分别拆分为训练集(X_train、Y_train)和测试集(X_test、Y_test),同时设置 random_state 保证每次划分的结果一致,方便复现。
3. 模型训练与预测
初始化高斯朴素贝叶斯模型,然后调用 fit 方法,传入训练集的 X_train 和 Y_train,让模型学习像素值和数字标签之间的关联。训练完成后,调用 predict 方法,传入测试集的 X_test,得到模型对测试集的预测标签 Y_pred。
4. 模型评估
最后用 accuracy_score 工具,将测试集的真实标签 Y_test 和预测标签 Y_pred 传入,计算模型的准确率。通过这个准确率,我们可以判断模型的识别效果 —— 比如准确率达到 90% 以上,说明模型在手写数字识别任务上表现较好。
五、学习收获与总结
通过本次学习,我不仅掌握了朴素贝叶斯的理论逻辑,还能通过实际代码实现具体任务,主要有以下几点收获:
算法优势明确:朴素贝叶斯的 “特征独立假设” 虽然简化了现实情况,但大大降低了计算复杂度,尤其是在数据量不大或特征维度较高(如文本)的场景中,效率很高,而且对小样本数据的适应性较好,不需要大量数据就能训练出有一定效果的模型。
模型选择有章可循:核心是根据特征数据的类型匹配模型 —— 如果是离散型的计数数据(如单词出现次数),选多项式朴素贝叶斯;如果是连续型数据(如像素值、温度),选高斯朴素贝叶斯;如果是二值化数据(如特征是否存在),选伯努利朴素贝叶斯,不用再盲目尝试不同模型。
参数设置需注意细节:拉普拉斯平滑(alpha 参数)是避免 “零概率” 问题的关键,实际应用中很少会设为 0,默认的 1.0 是比较安全的选择;先验概率的设置也会影响模型效果,如果有领域知识可以手动设置 class_prior,没有的话让模型自动计算(默认 None)即可。