朴素贝叶斯是一种简单但出人意料地强大的预测建模算法。
在这篇文章中,您将了解用于分类的朴素贝叶斯算法。阅读本文后,您将了解:
- 朴素贝叶斯使用的表示形式,即模型写入文件时实际存储的内容。
- 如何使用学习到的模型进行预测。
- 如何从训练数据中学习朴素贝叶斯模型。
- 如何为朴素贝叶斯算法最好地准备数据。
- 在哪里可以找到更多关于朴素贝叶斯的信息。
这篇文章是为开发人员编写的,不假定您有任何统计或概率背景,尽管了解一点概率也无妨。
通过我的新书《掌握机器学习算法》启动您的项目,其中包括分步教程和所有示例的Excel电子表格文件。
让我们开始吧。

机器学习中的朴素贝叶斯
图片来源:John Morgan,部分权利保留。
贝叶斯定理快速介绍
在机器学习中,我们通常对给定数据 (d) 的最佳假设 (h) 感兴趣。
在分类问题中,我们的假设 (h) 可能是为新的数据实例 (d) 分配的类别。
选择给定数据(我们可以用作我们关于问题的先验知识)的最可能假设的最简单方法之一。贝叶斯定理提供了一种计算给定先验知识的假设概率的方法。
贝叶斯定理表述为:
P(h|d) = (P(d|h) * P(h)) / P(d)
其中
- P(h|d) 是在数据 d 下假设 h 的概率。这称为后验概率。
- P(d|h) 是在假设 h 为真时数据 d 的概率。
- P(h) 是假设 h 为真的概率(与数据无关)。这称为 h 的先验概率。
- P(d) 是数据的概率(与假设无关)。
您可以看到,我们感兴趣的是从先验概率 p(h) 以及 P(D) 和 P(d|h) 计算后验概率 P(h|d)。
在计算了许多不同假设的后验概率后,您可以选择概率最高的假设。这就是最大可能假设,可以正式称为最大后验 (MAP) 假设。
这可以写成:
MAP(h) = max(P(h|d))
或者
MAP(h) = max((P(d|h) * P(h)) / P(d))
或者
MAP(h) = max(P(d|h) * P(h))
P(d) 是一个归一化项,它允许我们计算概率。当我们对最可能假设感兴趣时,我们可以删除它,因为它是一个常数,仅用于归一化。
回到分类问题,如果我们的训练数据中每个类别的实例数量相等,那么每个类别的概率(例如 P(h))将相等。同样,这将是我们方程中的一个常数项,我们可以将其删除,这样我们就得到:
MAP(h) = max(P(d|h))
这是一个有用的练习,因为在进一步阅读朴素贝叶斯时,您可能会看到所有这些形式的定理。
获取您的免费算法思维导图

方便的机器学习算法思维导图样本。
我创建了一份方便的思维导图,其中包含60多种按类型组织的算法。
下载、打印并使用它。
还可以独家访问机器学习算法电子邮件迷你课程。
朴素贝叶斯分类器
朴素贝叶斯是一种用于二元(两类)和多类分类问题的分类算法。当使用二元或分类输入值进行描述时,该技术最容易理解。
它被称为朴素贝叶斯或白痴贝叶斯,因为每个假设的概率计算被简化,使其计算变得可行。它们没有试图计算每个属性值 P(d1, d2, d3|h),而是假设在给定目标值的情况下它们是条件独立的,并计算为 P(d1|h) * P(d2|H) 等。
这是一个非常强的假设,在实际数据中极不可能,即属性之间没有相互作用。然而,这种方法在不满足此假设的数据上表现出惊人的良好。
朴素贝叶斯模型使用的表示
朴素贝叶斯的表示是概率。
学习到的朴素贝叶斯模型的概率列表存储到文件中。这包括:
- 类别概率:训练数据集中每个类别的概率。
- 条件概率:给定每个类别值的每个输入值的条件概率。
从数据中学习朴素贝叶斯模型
从训练数据中学习朴素贝叶斯模型速度很快。
训练速度快,因为只需要计算每个类别的概率以及给定不同输入 (x) 值时每个类别的概率。无需通过优化程序拟合系数。
计算类别概率
类别概率就是属于每个类别的实例频率除以实例总数。
例如,在二元分类中,实例属于类别 1 的概率将计算为:
P(class=1) = count(class=1) / (count(class=0) + count(class=1))
在最简单的情况下,对于每个类别具有相同数量实例的二元分类问题,每个类别的概率将为 0.5 或 50%。
计算条件概率
条件概率是给定类别值的每个属性值的频率除以具有该类别值的实例频率。
例如,如果“天气”属性具有“晴朗”和“下雨”值,并且类别属性具有“出门”和“待在家里”的类别值,那么每个天气值对每个类别值的条件概率可以计算为:
- P(weather=sunny|class=go-out) = count(instances with weather=sunny and class=go-out) / count(instances with class=go-out)
- P(weather=sunny|class=stay-home) = count(instances with weather=sunny and class=stay-home) / count(instances with class=stay-home)
- P(weather=rainy|class=go-out) = count(instances with weather=rainy and class=go-out) / count(instances with class=go-out)
- P(weather=rainy|class=stay-home) = count(instances with weather=rainy and class=stay-home) / count(instances with class=stay-home)
使用朴素贝叶斯模型进行预测
给定一个朴素贝叶斯模型,您可以使用贝叶斯定理对新数据进行预测。
MAP(h) = max(P(d|h) * P(h))
以上述为例,如果我们有一个天气为晴朗的新实例,我们可以计算:
出门 = P(weather=sunny|class=go-out) * P(class=go-out)
待在家里 = P(weather=sunny|class=stay-home) * P(class=stay-home)
我们可以选择计算值最大的类别。我们可以通过以下方式将其归一化为概率:
P(go-out|weather=sunny) = go-out / (go-out + stay-home)
P(stay-home|weather=sunny) = stay-home / (go-out + stay-home)
如果我们有更多的输入变量,我们可以扩展上面的例子。例如,假设我们有一个“汽车”属性,其值为“正常工作”和“损坏”。我们可以将此概率乘入方程。
例如,下面是“出门”类别标签的计算,其中添加了设置为“正常工作”的汽车输入变量:
出门 = P(weather=sunny|class=go-out) * P(car=working|class=go-out) * P(class=go-out)
高斯朴素贝叶斯
朴素贝叶斯可以扩展到实值属性,最常见的方法是假设高斯分布。
朴素贝叶斯的这种扩展称为高斯朴素贝叶斯。可以使用其他函数来估计数据的分布,但高斯(或正态分布)最容易处理,因为您只需要从训练数据中估计均值和标准差。
高斯朴素贝叶斯的表示
上面,我们使用频率计算了每个类别的输入值的概率。对于实值输入,我们可以计算每个类别输入值 (x) 的均值和标准差来概括分布。
这意味着除了每个类别的概率之外,我们还必须存储每个输入变量在每个类别中的均值和标准差。
从数据中学习高斯朴素贝叶斯模型
这就像计算每个类别值的每个输入变量 (x) 的均值和标准差一样简单。
mean(x) = 1/n * sum(x)
其中 n 是实例数,x 是训练数据中输入变量的值。
我们可以使用以下方程计算标准差:
标准差(x) = sqrt(1/n * sum(xi-mean(x)^2 ))
这是每个 x 值与 x 平均值的平均平方差的平方根,其中 n 是实例数,sqrt() 是平方根函数,sum() 是求和函数,xi 是第 i 个实例的 x 变量的特定值,mean(x) 如上所述,^2 是平方。
使用高斯朴素贝叶斯模型进行预测
新 x 值的概率使用高斯概率密度函数 (PDF) 计算。
在进行预测时,可以将这些参数与变量的新输入一起插入高斯 PDF,高斯 PDF 将反过来提供该新输入值在该类别中的概率估计。
pdf(x, mean, sd) = (1 / (sqrt(2 * PI) * sd)) * exp(-((x-mean^2)/(2*sd^2)))
其中 pdf(x) 是高斯 PDF,sqrt() 是平方根,mean 和 sd 是上面计算的均值和标准差,PI 是数值常数,exp() 是数值常数 e 或欧拉数的幂,x 是输入变量的输入值。
然后,我们可以将概率代入上述方程,以使用实值输入进行预测。
例如,通过天气和汽车的数值调整上述计算之一:
出门 = P(pdf(weather)|class=go-out) * P(pdf(car)|class=go-out) * P(class=go-out)
最好地为朴素贝叶斯准备数据
- 分类输入:朴素贝叶斯假设标签属性,例如二元、分类或名义属性。
- 高斯输入:如果输入变量是实值,则假定为高斯分布。在这种情况下,如果数据的单变量分布是高斯分布或接近高斯分布,则算法将表现更好。这可能需要删除异常值(例如,与均值相差 3 或 4 个标准差以上的值)。
- 分类问题:朴素贝叶斯是一种分类算法,适用于二元和多类分类。
- 对数概率:计算不同类别值的可能性涉及将许多小数字相乘。这可能导致数值精度下溢。因此,使用概率的对数变换以避免这种下溢是一种好习惯。
- 核函数:除了假设数值输入值的高斯分布外,还可以使用更复杂的分布,例如各种核密度函数。
- 更新概率:当有新数据可用时,您可以简单地更新模型的概率。如果数据频繁更改,这会很有帮助。
进一步阅读
您可能还会对另外两篇关于朴素贝叶斯的文章感兴趣:
我喜欢书。下面是一些适合开发人员的优秀通用机器学习书籍,它们涵盖了朴素贝叶斯:
- 数据挖掘:实用机器学习工具和技术,第88页
- 应用预测建模,第353页
- 人工智能:一种现代方法,第808页
- 机器学习,第6章
总结
在这篇文章中,您发现了用于分类的朴素贝叶斯算法。您了解了:
- 贝叶斯定理及其在实践中的计算方法。
- 朴素贝叶斯算法,包括表示、进行预测和学习模型。
- 朴素贝叶斯对实值输入数据的适应,称为高斯朴素贝叶斯。
- 如何为朴素贝叶斯准备数据。
您对朴素贝叶斯或本文有任何疑问吗?请留言提问,我将尽力回答。
嗨,如何理解这句话:
*如果我们的训练数据中每个类别有偶数个实例,那么每个类别的概率(例如 P(h))将相等*?
您能就此给出一些清晰简洁的示例吗?
谢谢?
当然,如果您有两个类别“红色”和“蓝色”,每个类别有50个样本,那么这些类别的观测值数量相等。
从总体中抽取任何随机样本属于某个类别的概率是0.5。
希望这能有所帮助。
是的,我现在明白了。我把“even”这个词理解为任何偶数,比如4、6或8。我的错!
对于基于多个特征的分类,是否需要多变量高斯分布来决定类别标签,或者是否足以决定每个特征的可能性,考虑到每个特征在给定类别 yi 的情况下服从高斯分布,然后简单地将它们相乘得到可能性?如果答案是肯定的,您能否给我提供一些参考文献?
提前感谢!
这取决于问题。朴素贝叶斯将假设独立的 Gaussian 分布。
我如何使用朴素贝叶斯机器学习来检测和预防 SQL 注入攻击,我的问题是,当攻击者注入恶意代码时,这些代码会保存在服务器上,然后算法开始工作吗?或者实际发生了什么?
这取决于您如何构建您的问题。
https://machinelearning.org.cn/how-to-define-your-machine-learning-problem/
嘿,关于高斯朴素贝叶斯模型,您如何评估条件概率 P(pdf(weather)|class=go-out)?pdf(x, mean, sd) 返回的是概率密度函数,而不是概率(有时值可能高于 1)。您能澄清一下吗?
嘿,你有没有时间看看这个问题?
你说得对,PDF 不提供概率(而是当支持趋于 0 时,一个区域的极限),但是由于朴素贝叶斯的目标是找到 argmax,我们可以用 PDF 来实现,因为最可能的值具有更高的 PDF。
嗨,Jason博士,
文本分类最好的机器学习算法是什么?
谢谢,
尝试一套工具,看看哪种最适合您的特定数据。
带有词嵌入的 CNN 表现非常好。
嗨,Jason博士,
解释得很好。
1) 有没有一篇文章解释生成模型和判别模型的?或者您能否对这两种模型进行一些直观的解释。
2) 解释 HMM、CRF 和 MEMM 的文章?
我没有关于这些主题的文章,希望将来能涵盖它们。
尊敬的 Jason 博士,感谢您的回复。我期待那些主题。谢谢。
嗨,它如何成为一种惰性算法?您能告诉我一些使用朴素贝叶斯的应用程序吗?
您可以将其应用于大多数预测建模问题,并将结果与其他算法进行比较,以确定是否应该使用它。
你好,先生,我正在进行社交媒体分析,以预测社会犯罪(网络欺凌、黑客等)。
我们如何使用朴素贝叶斯算法来预测我们设置的多类社会犯罪?
(例如,特定推文或帖子属于指定的社会犯罪类别,以及我们如何训练模型来识别和预测社会犯罪)
我建议您使用 sklearn 实现。
你好,先生,我想用朴素贝叶斯算法来预测献血者下一次献血,根据他们的年龄。先生,这种预测可能吗?
我建议您按照这个过程解决您的问题:
https://machinelearning.org.cn/start-here/#process
感谢 Jason 提供的丰富信息。我有一个问题。在 MAP 的定义中,您提到似然与假设的概率相乘。根据您的示例,我了解到此假设是一些输出类别的概率。我查阅了其他博客,他们提到要计算 MAP 需要与模型参数的先验概率相乘。请参阅以下链接。
https://wiseodd.github.io/techblog/2017/01/01/mle-vs-map/
https://www.quora.com/What-is-the-difference-between-Maximum-Likelihood-ML-and-Maximum-a-Posteri-MAP-estimation
这是否意味着 MAP 是贝叶斯规则的通用公式,可以与输出类别先验和模型参数先验一起使用?我想我在这里遗漏了一些非常基本的东西。
MAP 是否同时用于模型?
是的,您应该包括先验,我在这里排除了它,因为它对每个类别都相同。
我就是看不够您的文章,伙计!我没有问题,但我真的很想留下这条评论,鼓励您继续撰写这样易于理解和解释的文章。
请继续保持出色的工作!
谢谢!
你好 Jason 先生,谢谢您的帖子。
我有一个问题,先生
1. 我是否必须对所有似然和先验概率使用对数才能进行预测?
(背景:我有一个心脏病风险数据集,其中包含离散和连续数据。我计算了离散数据的似然,但当我计算连续数据时,我得到似然为零,现在我知道这是由于数值精度下溢造成的。现在我很困惑;我是否必须将所有离散和连续的似然以及先验都转换为对数?(同上))……
2. 或者我应该只将连续数据转换为对数?(如果我这样做,它会改变预测吗?)。
3. 最后,如果进行了对数转换,值是负数,那么我应该只取大小还是符号也用于预测?
我需要这方面的帮助。谢谢先生
我认为您的 PDF 公式有误。
pdf(x, mean, sd) = (1 / (sqrt(2 * PI) * sd)) * exp(-((x-mean^2)/(2*sd^2)))
应该是??
pdf(x, mean, sd) = (1 / (sqrt(2 * PI) * sd)) * exp(-((x-mean)^2/(2*sd^2)))
否则可能会出现溢出问题
谢谢。
有哪些 Python 模块实现了朴素贝叶斯算法?
scikit-learn 库
https://scikit-learn.cn/stable/modules/generated/sklearn.naive_bayes.GaussianNB.html
哇,这是我见过对朴素贝叶斯最好的解释了……你太棒了:-)
谢谢。
你好,您能解释一下一个属性的标准差值与朴素贝叶斯预测之间的相关性吗?因为我有一些数据集,其中一个数据集的标准差非常低,准确度结果很差,但对于相同的数据集,我尝试了决策树,结果比朴素贝叶斯更好。
我不认为它们之间有关系。
你好,假设我想找到两个数据块之间的 KL 散度,我可以使用高斯朴素贝叶斯来查找这些数据块的概率分布吗?我有两个多元数据块(一个因变量和多个自变量),我想找到这两个数据块概率分布之间的距离。如何找到它?请指导。
散度适用于一个变量或一个离散事件。抱歉,我不能立刻确定多元 KL 散度。
Jason 博士的文章写得非常好。我还没有见过如此清晰地解释贝叶斯理论的文章。
然而,您能否澄清以下语句中的“P”?
P(pdf(weather)|class=go-out)。
如果它表示概率,那么我们如何获得密度值的概率呢?因为根据您的文章,pdf 本身会提供一个值,该值将与另一个 pdf 值进行比较。因此,“P”的用法对我来说不清楚。提前感谢!
如果您阅读实现部分,会理解得更好:https://machinelearning.org.cn/naive-bayes-classifier-scratch-python/
但我同意你的看法。这里的重点是说,我们正在计算每个特征的概率并将其相乘。但是如何获得概率取决于该特征的 pdf。高斯朴素贝叶斯假设它们服从正态分布。
非常感谢您在这里所做的出色工作,您对概念的解释非常透彻且易于理解。
Kris,非常欢迎您!我们非常感谢您的支持!