机器学习朴素贝叶斯教程

朴素贝叶斯是一种非常简单的分类算法,它对每个输入变量的独立性做出了强有力的假设。

尽管如此,它在大量的领域中已被证明是有效的。在本帖中,您将了解朴素贝叶斯算法在分类数据中的应用。阅读本帖后,您将了解:

  • 如何处理朴素贝叶斯中的分类数据。
  • 如何为朴素贝叶斯模型准备类别和条件概率。
  • 如何使用学习到的朴素贝叶斯模型进行预测。

本帖是为开发者编写的,不假设您具有统计学或概率论背景。请打开电子表格,跟随一起学习。如果您对朴素贝叶斯有任何疑问,请在评论区提问,我将尽力回答。

用我的新书《精通机器学习算法》快速启动您的项目,书中包含分步教程和所有示例的Excel电子表格文件。

让我们开始吧。

Naive Bayes Tutorial for Machine Learning

机器学习朴素贝叶斯教程
照片作者:Beshef,部分权利保留。

教程数据集

该数据集是人为构造的。它描述了两个分类输入变量和一个具有两个输出的类别变量。

我们可以将这些数据转换为数字。每个输入只有两个值,输出类别变量也有两个值。我们可以将每个变量转换为二进制,如下所示:

变量:天气

  • 晴天 = 1
  • 雨天 = 0

变量:汽车

  • 工作 = 1
  • 坏了 = 0

变量:类别

  • 出行 = 1
  • 在家 = 0

因此,我们可以重述数据集如下:

这可以使数据在电子表格或代码中更容易处理,如果您正在跟随操作的话。

获取您的免费算法思维导图

Machine Learning Algorithms Mind Map

方便的机器学习算法思维导图样本。

我创建了一份方便的思维导图,其中包含60多种按类型组织的算法。

下载、打印并使用它。


还可以独家访问机器学习算法电子邮件迷你课程。

 

 

学习朴素贝叶斯模型

朴素贝叶斯模型需要从数据集中计算两种类型的数量:

  • 类别概率。
  • 条件概率。

让我们从类别概率开始。

计算类别概率

这是一个二分类问题,而且由于我们是人为构造的数据集,所以我们已经知道了每个类别的概率。

尽管如此,我们仍然可以计算类别0和类别1的类别概率,如下所示:

  • P(类别=1) = count(类别=1) / (count(类别=0) + count(类别=1))
  • P(类别=0) = count(类别=0) / (count(类别=0) + count(类别=1))

或者

  • P(类别=1) = 5 / (5 + 5)
  • P(类别=0) = 5 / (5 + 5)

计算结果是,任何数据实例属于类别0或类别1的概率都是0.5。

计算条件概率

条件概率是每个输入值给定每个类别值的概率。

该数据集的条件概率可以计算如下:

天气输入变量

  • P(天气=晴天|类别=出行) = count(天气=晴天 and 类别=出行) / count(类别=出行)
  • P(天气=雨天|类别=出行) = count(天气=雨天 and 类别=出行) / count(类别=出行)
  • P(天气=晴天|类别=在家) = count(天气=晴天 and 类别=在家) / count(类别=在家)
  • P(天气=雨天|类别=在家) = count(天气=雨天 and 类别=在家) / count(类别=在家)

代入数值,我们得到:

  • P(天气=晴天|类别=出行) = 0.8
  • P(天气=雨天|类别=出行) = 0.2
  • P(天气=晴天|类别=在家) = 0.4
  • P(天气=雨天|类别=在家) = 0.6

汽车输入变量

  • P(汽车=工作|类别=出行) = count(汽车=工作 and 类别=出行) / count(类别=出行)
  • P(汽车=坏了|类别=出行) = count(汽车=坏了 and 类别=出行) / count(类别=出行)
  • P(汽车=工作|类别=在家) = count(汽车=工作 and 类别=在家) / count(类别=在家)
  • P(汽车=坏了|类别=在家) = count(汽车=坏了 and 类别=在家) / count(类别=在家)

代入数值,我们得到:

  • P(汽车=工作|类别=出行) = 0.8
  • P(汽车=坏了|类别=出行) = 0.2
  • P(汽车=工作|类别=在家) = 0.2
  • P(汽车=坏了|类别=在家) = 0.8

现在我们有了使用朴素贝叶斯模型进行预测所需的一切。

用朴素贝叶斯进行预测

我们可以使用贝叶斯定理进行预测。

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) 是数据的概率(不考虑假设)。

事实上,我们不需要概率来预测新数据实例最可能的类别。我们只需要分子以及产生最大响应的类别,这将是预测的输出。

MAP(h) = max(P(d|h) * P(h))

让我们用数据集中的第一个记录,并使用我们学习到的模型来预测它所属的类别。

天气=晴天,汽车=工作

我们将模型中这两种类别的概率代入并计算响应。从“出行”输出的响应开始。我们将条件概率相乘,然后乘以任何实例属于该类别的概率。

  • 出行 = P(天气=晴天|类别=出行) * P(汽车=工作|类别=出行) * P(类别=出行)
  • 出行 = 0.8 * 0.8 * 0.5
  • 出行 = 0.32

我们可以对在家的情况进行相同的计算:

  • 在家 = P(天气=晴天|类别=在家) * P(汽车=工作|类别=在家) * P(类别=在家)
  • 在家 = 0.4 * 0.2 * 0.5
  • 在家 = 0.04

我们可以看到0.32大于0.04,因此我们预测此实例为“出行”,这是正确的。

我们可以对整个数据集重复此操作,如下所示:

如果我们统计预测值与实际类别值的比较,我们可以获得80%的准确率,考虑到数据集中存在冲突的例子,这是一个很好的结果。

总结

在本帖中,您将了解如何从零开始实现朴素贝叶斯。您学到了:

  • 如何使用朴素贝叶斯处理分类数据。
  • 如何从训练数据中计算类别概率。
  • 如何从训练数据中计算条件概率。
  • 如何使用学习到的朴素贝叶斯模型对新数据进行预测。

您对朴素贝叶斯或本帖有任何疑问吗?
留下评论提问,我将尽力回答。

了解机器学习算法的工作原理!

Mater Machine Learning Algorithms

几分钟内了解算法如何工作

...只需算术和简单示例

在我的新电子书中探索如何实现
精通机器学习算法

它涵盖了**10种顶级算法**的**解释**和**示例**,例如:
_线性回归_、_k-近邻_、_支持向量机_等等...

最后,揭开
机器学习算法的神秘面纱

跳过学术理论。只看结果。

查看内容

49条回复关于“机器学习朴素贝叶斯教程”

  1. Royi 2016年4月13日 上午6:26 #

    您真的应该在您的博客中添加MathJax来正确显示数学公式。

    • Jason Brownlee 2016年4月13日 上午7:27 #

      您可能是对的,但是不使用清晰的公式可能会让开发者觉得不那么令人生畏。

  2. Ben 2016年10月23日 下午8:34 #

    Jason您好,我很高兴您的文章对初学者来说如此易于理解!这篇写得非常清晰简单,谢谢!

    我想知道这个朴素贝叶斯分类器如何用于“预测”?例如,您原始的数据集中不包含以下组合:
    – 天气=雨天
    – 汽车=工作。
    您如何使用该模型来预测给定这两个输入时每个类别的概率?

    • Jason Brownlee 2016年10月24日 上午7:04 #

      谢谢Ben,

      帖子里标题为“用朴素贝叶斯进行预测”的部分解释了如何根据新观察进行预测。

  3. eng adebayo 2017年3月31日 上午2:36 #

    您的代码出现了这些错误:
    File “C:\Users\Eng Adebayo\Documents\pybrain-master\naive-bayes.py”, line 103, in
    main()
    File “C:\Users\Eng Adebayo\Documents\pybrain-master\naive-bayes.py”, line 93, in main
    dataset = loadCsv(filename)
    File “C:\Users\Eng Adebayo\Documents\pybrain-master\naive-bayes.py”, line 12, in loadCsv
    dataset[i] = [float(x) for x in dataset[i]]
    File “C:\Users\Eng Adebayo\Documents\pybrain-master\naive-bayes.py”, line 12, in
    dataset[i] = [float(x) for x in dataset[i]]
    ValueError: 无法将字符串转换为浮点数
    >>>

  4. Zaidan14 2017年5月2日 下午4:52 #

    你好,
    我在算法思维导图中找不到SVM!它属于哪个类别?
    非常感谢!

  5. Luky 2017年7月27日 上午4:54 #

    您好,这篇文章非常棒,特别是对于我这样数学不太好的人来说(维基百科上的内容看起来比这里要难得多),但也许我理解错了,但条件概率是否正确?

    P(天气=晴天|类别=出行) = count(天气=晴天 and 类别=出行) / count(类别=出行)

    让我们举个另一个例子。假设输入是职业,输出是内向/外向。假设我采访100个人,询问他们的职业以及他们是内向还是外向。

    现在,假设我只遇到3个IT工作者,而且他们都是内向的。其余97人也是其他职业且内向(仅为简化起见)。

    现在,如果我按照您的例子,那么IT工作者是内向者的概率是:

    P(职业=IT|类别=内向) = count(职业=IT=内向) / count(类别=内向)

    也就是说:

    3 / 100 = 3% 的IT工作者是内向的。但这是否正确?我们采访了3个IT人员,所有人都说是。难道不应该是:

    P(职业=IT|类别=内向) = count(职业=IT=内向) / count(职业=IT)?

    这样我们就得到了100%,这反映了我们的样本。或者?也许天气样本也类似?

    并且应该是:

    P(天气=晴天|类别=出行) = count(天气=晴天 and 类别=出行) / count(天气=晴天)?

    Luky 敬上

    • Luky 2017年7月27日 上午5:30 #

      也许两种比例都有意义,但您的比例似乎更容易受到数据结构的影响。假设我只有10k人中的3个IT工作者,那么IT内向者的比例将是10k个内向者中的3个(假设),这将是一个非常小的数字,而第二种比例(IT内向者/IT工作者)则不易受到不平等分布样本数据的影响。(即使只有3个IT工作者,它也显示为100%)。但这只是我的看法,我对您的观点很好奇:)。

    • Jason Brownlee 2017年7月27日 上午8:15 #

      数学是正确的。但是您问的是不同的问题。

      IT工作者和内向者的概率是多少?与我们知道一个人在IT工作的情况下,他是内向者的概率是多少?

  6. Luky 2017年7月27日 上午4:57 #

    更正:“3%的IT工作者是内向的”= IT工作者是内向者的概率为3%。

  7. Luky 2017年7月27日 上午6:28 #

    但是我现在看到,按照文章的比例概率计算,在我的例子中,外向者的概率会是0,这将小于4%的内向者,因此结果会是内向者,这是一个正确的预测……所以这有一定道理……汗。数学和逻辑真是吓人😛

  8. Milind Mahajani 2017年8月18日 下午8:11 #

    非常棒的帖子——解释得太好了!

    请指导一下,当有多个输入变量时,例如除了天气和汽车之外,还有“有小说要完成”和“感到疲倦”,我该如何预测类别?

    在这种情况下,如何扩展该方法?

  9. Anebras Ahmed 2017年10月29日 上午5:06 #


    我需要使用朴素贝叶斯来检测和防止SQL注入。
    这个目的的最佳模型是什么?
    并且当分类器将客户端请求识别为SQL注入攻击时,之后应该发生什么?是将请求重定向到另一个页面,还是在服务器端设置超时,还是将请求传递给代理?
    谢谢^_^

  10. Abubakar Bello 2018年7月5日 上午12:40 #

    嗨!
    干得好,Browwnlee博士。但我仍然需要您的帮助,请您展示一下如何计算像Pima Indian Diabetes Dataset这样的训练数据的条件概率。

  11. salman al satary 2018年8月5日 下午5:19 #

    你好!
    你是否找到了检测SQL注入的最佳模型?

    • Jason Brownlee 2018年8月6日 上午6:25 #

      在您的特定数据集上尝试一套模型,并发现哪种效果最好。

  12. Paritosh Gupta 2018年8月17日 下午1:34 #

    Jason,

    这个博客写得非常有趣且简洁,几乎每个人都能理解。但是,我们如何利用您的方法来处理连续变量呢?

    • Jason Brownlee 2018年8月17日 下午2:06 #

      谢谢。

      您可以使用高斯分布来近似变量的概率分布。

      这被称为高斯朴素贝叶斯。

  13. Zachary Omariba 2018年11月22日 下午6:49 #

    这种方法看起来很简单,但对于一个有许多变量值(如2000条记录)的表格,我该如何使用它?例如,假设我有一个变量电压和电池充电和放电的时间,并且我想找到剩余有用寿命,并将阈值设定为1.4V,电池电压为2.1V。鉴于这些变量有数千条数据,我该如何使用贝叶斯?

  14. jcatanz 2018年12月12日 上午6:07 #

    感谢您对朴素贝叶斯分类器的精彩概述!

  15. Felipe Martinez 2019年2月4日 下午3:37 #

    Jason博士您好
    我是Python编程语言和机器学习方面的新手,我正在练习机器学习算法。在《从零开始的机器学习算法》一书中第12章“朴素贝叶斯”的练习中,我使用“Iris.csv”数据集运行得很好,但在用另一个数据集“Abseinteeism_at_work.csv”进行练习时,出现了“ZeroDivisionError: float division by zero”的错误。我在网上查找了解决错误的方法,并且已经花了几天时间,但在Stack Overflow链接上也找不到解决方案。您能否帮助我解决这个问题,以便我能继续学习这个领域?

    • Jason Brownlee 2019年2月5日 上午8:13 #

      也许数据中有一些特殊的东西导致了这个问题?

      也许可以尝试逐一删除输入列,看看它对模型有何影响,以及是否能解决问题。这将帮助您缩小问题的范围。

      告诉我进展如何。

  16. amjad 2019年2月12日 上午4:34 #

    先生,非常感谢。您在NB方法中是否有任何插补方法?

    • Jason Brownlee 2019年2月12日 上午8:08 #

      我认为不行。

      你到底遇到了什么问题?

  17. Michael Adjeisah 2019年3月5日 下午12:34 #

    嗨,Jason,
    我遇到了这些错误:

    回溯(最近一次调用)

    File “”, line 17, in
    main()

    File “”, line 9, in main
    summaries = summarizeByClass(trainingSet)

    File “”, line 43, in summarizeByClass
    for classValue, instances in separated.iteritems()

    AttributeError: ‘dict’ object has no attribute ‘iteritems’

    • Michael Adjeisah 2019年3月5日 下午12:49 #

      抱歉,我明白了。

  18. Nilesh 2019年4月12日 下午6:15 #

    谢谢 Jason 先生

  19. Dioniz 2019年12月3日 上午12:16 #

    Hi Jason,感谢您提供的清晰教程!

    但是,有一个潜在的问题

    P(h|d) = (P(d|h) * P(h)) / P(d)

    如果我们计算P(d),其中d = 天气是晴天且汽车是工作,我们得到0.6 * 0.5 = 0.3
    但是 (P(d|h) * P(h)) = 0.32。

    因此 P(h|d) = 0.32 / 0.3,这大于1。

    概率可能大于1吗?

    提前感谢您的回复!

    • Jason Brownlee 2019年12月3日 上午4:52 #

      不,概率必须在0到1之间。

      • Dioniz 2019年12月3日 上午6:10 #

        那么就有一个问题。当h=出行,d=(天气是晴朗且汽车是工作)

        P(h|d) = 0.32 / 0.3 = 1.0666…

        您对此有什么想法吗?

        • Jason Brownlee 2019年12月3日 下午1:30 #

          请注意,“|”表示“给定”,而不是“除”。

          • Dioniz 2019年12月7日 上午6:09 #

            感谢您的回复。

            “/”我指的是这个公式中的除号。

            P(h|d) = (P(d|h) * P(h)) / P(d)

            我知道我们不一定需要这个除法来进行朴素贝叶斯算法,但是,我仍然好奇地计算了P(h|d)。

            我发现:

            P(h|d) = (P(d|h) * P(h)) / P(d) = 0.8 * 0.8 * 0.5 / 0.3 = 0.32 / 0.3 = 1.0666…

            h = 出行
            d = (天气好,汽车工作)

            P(d) = P(天气好,汽车工作) = P(天气好) * P(汽车工作) = 0.6 * 0.5 = 0.3

            因此,P(h|d) = 1.0666… 一方面这是不可能的。但另一方面,我找不到计算概率的问题。

          • Jason Brownlee 2019年12月8日 上午5:59 #

            我明白了,谢谢。

  20. Prateek Pareek 2020年6月4日 上午3:08 #

    嗨,Jason,

    我非常感谢您让机器学习对非技术专业人士来说如此容易。您解释朴素贝叶斯的方式非常容易理解。我读过大量的博客和课程,但我发现当我从您的博客学习时,我学得更容易。您让机器学习对我来说非常有趣和简单。非常感谢!

  21. Dioniz 2020年6月30日 上午3:35 #

    嗨,Jason,

    我们为什么要计算这些概率?

    我们想得到 P(类别=出行 | 天气=晴天, 汽车=工作),因此,我们可以直接从您的表格中找到它,而无需进行任何朴素的假设。

    当类别=出行时有5种情况,其中4种出现在天气=晴天且汽车=工作时。这很简单意味着:
    P(类别=出行 | 天气=晴天, 汽车=工作) = 4/5

    然后我们可以用类似的方式得到P(类别=在家 | 天气=晴天, 汽车=工作)。有5种类别=在家的情况,只有1种出现在天气=晴天且汽车=工作时。因此:
    P(类别=在家 | 天气=晴天, 汽车=工作) = 1/5

    就是这样。那么我们为什么需要您所有的计算呢?如果知道答案,提前感谢。

    • Jason Brownlee 2020年6月30日 上午6:29 #

      好问题,我想在这种情况下,我正在尝试演示基于概率运行的朴素贝叶斯方法。

  22. Liron 2021年3月17日 下午8:43 #

    Hi Jason,感谢您的有用教程!如何在不使用外部包的情况下,使用多个类别而不是二元类别(晴天、雨天、多云、下雪……)来实现它?您知道将类别转换为数字的有用方法吗?再次感谢!

    • Jason Brownlee 2021年3月18日 上午5:20 #

      上述示例直接推广到多个类别,例如从二项概率分布转换为多项概率分布。

  23. Muso Techmann 2023年9月19日 下午2:22 #

    你好 Jason,
    您得出结论,这个人为构造的数据集对于任何类别都有一个类别的概率,即50%。
    ( ==> 5 / (5+ 5).

    但是,对于第一个类别(晴天或雨天),有6个晴天和4个雨天。
    我的理解是否正确,是否犯了错误?
    我将第六个晴天改成了雨天(如果从列的顶部计数)。

    仅供参考,您的教程布局非常简单易懂。谢谢您。
    这有助于激励我继续学习机器学习课程。毕竟,它看起来并不那么难。

    • James Carmichael 2023年9月20日 上午10:18 #

      感谢您的反馈Muso!您说得对!

留下回复

Machine Learning Mastery 是 Guiding Tech Media 的一部分,Guiding Tech Media 是一家领先的数字媒体出版商,专注于帮助人们了解技术。访问我们的公司网站以了解更多关于我们的使命和团队的信息。