朴素贝叶斯学习笔记:从原理到实战(J享)
一、先搞懂贝叶斯:从 “摸球” 到 “猜性别”
要学朴素贝叶斯,得先明白 “贝叶斯思想” 到底在解决啥问题。托马斯・贝叶斯是 18 世纪的英国数学家,他生前写了篇解决 “逆概” 问题的文章,死后才被认可 —— 现在我们用的贝叶斯方法,根源就在这。
先分清两个基础概念,用 “球” 和 “学生” 举例子,特别好懂:
- 正向概率:知道袋子里有 N 个白球、M 个黑球,摸出黑球的概率是多少?或者知道学校里 60% 是男生、40% 是女生,男生都穿长裤、女生一半穿长裤,随机选个学生穿长裤的概率是多少?这是 “已知条件算结果”,很直观。
- 逆向概率:闭着眼摸了几个球,根据球的颜色猜袋子里黑白球的比例;或者看到一个穿长裤的学生,猜他是女生的概率有多大?这是 “已知结果推条件”,也是贝叶斯要解决的核心问题。
拿 “猜穿长裤的是女生” 这个例子,我们可以一步步推导出贝叶斯公式。假设学校总人数是 U,穿长裤的女生数量是 “U× 女生概率(40%)× 女生穿长裤概率(50%)”,穿长裤的总人数是 “男生穿长裤人数 + 女生穿长裤人数”。最后算 “穿长裤的人里是女生的概率” 时,会发现总人数 U 能消掉,剩下的就是:
P (女生 | 穿长裤) = [P (女生)×P (穿长裤 | 女生)] / P (穿长裤)
这就是贝叶斯公式核心逻辑:P(A|B) = [P(A)×P(B|A)] / P(B) 。其中 P (A) 是 “先验概率”(比如女生占比 40%),P (B|A) 是 “条件概率”(女生穿长裤的概率),P (B) 是 “证据概率”(所有人穿长裤的概率)。
二、朴素贝叶斯:加个 “朴素” 假设,复杂问题变简单
“朴素” 俩字是关键 —— 它假设特征之间相互独立,互不影响。这个假设看起来有点 “理想化”,但实际用起来效果特别好,还能大幅减少计算量。比如判断邮件是不是垃圾邮件,朴素贝叶斯会认为 “邮件里的每个单词之间没关系”,不用考虑单词的语序,只算每个单词在垃圾邮件里出现的概率就行。
下面两个实战例子,能帮你彻底理解它的用法:
1. 拼写纠正:猜用户到底想输啥
比如用户输了 “tlp”,不在字典里,我们要猜他是想输 “top” 还是 “tip”。用贝叶斯的思路来拆解:
- 观测数据 D:用户实际输入的 “tlp”;
- 猜测 h:可能是 “top”“tip” 等;
- 目标是算 P (h|D)(已知输入 “tlp”,猜是 “top” 的概率)。
根据贝叶斯公式,P (h|D) = [P (h)×P (D|h)] / P (D)。这里 P (D) 对所有猜测都一样(都是 “输入 tlp” 的概率),可以忽略,所以只要比 P (h)×P (D|h) 就行:
- P (h) 是 “先验概率”:比如 “top” 在日常用词中出现的频率比 “tip” 高,那 P (“top”) 就更大;
- P (D|h) 是 “条件概率”:输入 “tlp” 是因为想输 “top” 却打错的概率(比如 “o” 和 “l” 键盘位置近)。
最后比下来,“top” 的 P (h)×P (D|h) 更大,所以优先猜用户想输 “top”。
2. 垃圾邮件分类:看单词就够了
给定一封邮件,判断是不是垃圾邮件(h + 代表垃圾邮件,h - 代表正常邮件),思路和拼写纠正类似:
- 邮件 D 由多个单词(d1、d2、…、dn)组成,目标算 P (h+|D) 和 P (h-|D),哪个大就归哪类;
- 先验概率 P (h+) 和 P (h-):统计邮件库里垃圾邮件、正常邮件的比例就行,比如 1000 封邮件里有 200 封垃圾邮件,那 P (h+) 就是 20%;
- 关键是算 P (D|h+)(垃圾邮件中出现这封邮件所有单词的概率):因为朴素贝叶斯假设单词独立,所以 P (D|h+) = P (d1|h+)×P (d2|h+)×…×P (dn|h+)。比如 “中奖” 这个词在垃圾邮件里出现过 100 次,垃圾邮件总单词数是 1000,那 P (“中奖”|h+) 就是 10%。
这样一步步算下来,就能轻松给邮件分类了。
三、三种常用朴素贝叶斯模型:选对模型事半功倍
学完原理,实际代码里该用哪种模型?得看数据类型,孙老师的课里重点讲了三种,用 scikit-learn 就能直接调用,特别方便:
模型 | 适用场景 | 关键参数 / 说明 |
---|---|---|
多项式朴素贝叶斯 | 离散型数据(如文本) | alpha:拉普拉斯平滑参数(默认 1.0,0 则不平滑);fit_prior:是否考虑先验概率(默认 True) |
高斯朴素贝叶斯 | 连续型数据(如身高、体重) | priors:先验概率,没给的话模型会自己算(极大似然法) |
伯努利朴素贝叶斯 | 二值离散数据(0/1) | alpha:平滑参数;binarize:二值化阈值(默认 0,None 代表已二值化) |
比如做文本分类(单词出现次数是离散值),用多项式朴素贝叶斯;做房价预测的辅助分类(面积、单价是连续值),用高斯朴素贝叶斯;判断文本里 “某单词是否出现”(1 = 出现,0 = 没出现),用伯努利朴素贝叶斯。
它们的核心 API 都差不多,比如 fit (X,Y) 是训练模型,predict (X) 是预测,score (X,Y) 是算准确率,上手很快。
四、用朴素贝叶斯做手写数字识别
最后跟着课上的练习试了下手写数字识别,步骤很简单,分享给大家:
- 先导入数据集:用 sklearn 自带的 load_digits,里面是 8×8 的手写数字图片数据;
- 选模型:手写数字的每个像素点是 0-16 的离散值(代表灰度),用多项式朴素贝叶斯就行;
- 训练和预测:分训练集测试集,调用 fit 训练,predict 预测,最后用 score 看准确率 —— 我跑的时候准确率能到 90% 左右,对于这么简单的模型来说,已经很能打了。