朴素贝叶斯分类的简单解释

575

我很难理解朴素贝叶斯的过程,想知道是否有人能用简单的英文逐步解释一下。我知道它是通过发生次数进行概率比较,但我不知道训练数据与实际数据集之间的关系。

请给我一个关于训练集扮演什么角色的解释。这里给出一个非常简单的水果例子,例如香蕉。

training set---
round-red
round-orange
oblong-yellow
round-red

dataset----
round-red
round-orange
round-red
round-orange
oblong-yellow
round-red
round-orange
oblong-yellow
oblong-yellow
round-red

19
如果您理解了贝叶斯定理,那么这很容易。如果您还没有阅读有关贝叶斯定理的内容,请尝试访问此链接http://yudkowsky.net/rational/bayes。 - Pinch
23
注意:下面的接受答案并不是传统朴素贝叶斯算法的典型示例,它主要是k最近邻实现。请相应阅读。 - chmullig
这是Oscar Bonilla关于贝叶斯定理的快速视觉描述 - http://oscarbonilla.com/2009/05/visualizing-bayes-theorem/ - Will
2
好的,如果一个人看到一个有一些点的图形,那并不意味着它是KNN :)如何计算概率完全取决于你自己。朴素贝叶斯使用先验乘以似然来计算它,这就是Yavar在他的答案中所展示的。如何得出这些概率在这里真的不重要。答案是绝对正确的,我没有看到任何问题。 - avinash shah
5个回答

1084

被认可的答案包含了许多k-NN(k近邻)算法元素,这是一种不同的算法。

k-NN和NaiveBayes都是分类算法。在概念上,k-NN使用“接近度”来对新实体进行分类。在k-NN中,“接近度”通过欧几里得距离或余弦距离等概念进行建模。相比之下,在NaiveBayes中,使用“概率”概念来对新实体进行分类。

由于问题涉及到Naive Bayes,以下是我如何向某人描述这些思想和步骤。我将尽可能用简单的英语少写方程式来解释它们。

首先,条件概率和贝叶斯定理

在某人能够理解和欣赏Naive Bayes的微妙之处之前,他们需要先了解一些相关的概念,即条件概率和贝叶斯定理。(如果您熟悉这些概念,请跳到标题为进入Naive Bayes的部分。)

条件概率的简单解释:在已知某件事情发生的情况下,另一件事情发生的概率是多少。

假设有某个结果O和某个证据E。从这些概率的定义方式来看:同时发生结果O和证据E的概率是:

(结果O发生的概率) 乘以 (已知结果O发生情况下,证据E发生的条件概率)

一个示例以理解条件概率:

假设我们有一组美国参议员。参议员可以是民主党人或共和党人。他们也可以是男性或女性。

如果我们随机选择一个参议员,那么这个人是女性民主党人的概率是多少?条件概率可以帮助我们回答这个问题。

(民主党人且女性参议员)的概率=参议员为民主党人的概率 乘以 已知他们是民主党人的情况下为女性的条件概率。

  P(Democrat & Female) = P(Democrat) * P(Female | Democrat) 

我们也可以以相反的方式计算出完全相同的结果:

  P(Democrat & Female) = P(Female) * P(Democrat | Female) 

理解贝叶斯定理

从概念上讲,这是一种从P(证据|已知结果)到P(结果|已知证据)的方法。通常,我们知道某些特定证据在给定已知结果的情况下被观察到的频率。我们必须利用这个已知事实来计算相反的情况,即计算给定证据的情况下发生该结果的可能性。

P(我们知道某些证据时发生某个结果) = P(我们知道某个结果时该证据发生)乘以Prob(结果),然后按P(证据)进行缩放

理解贝叶斯定理的经典例子:

Probability of Disease D given Test-positive = 

               P(Test is positive|Disease) * P(Disease)
     _______________________________________________________________
     (scaled by) P(Testing Positive, with or without the disease)

现在,以上都只是为了介绍朴素贝叶斯算法。

了解朴素贝叶斯

迄今为止,我们只讨论了一个证据的情况。实际上,我们需要根据多个证据来预测结果。在这种情况下,数学变得非常复杂。为了避免这种复杂性,一种方法是将多个证据“解耦”,并将每个证据看作是独立的。这就是为什么这被称为朴素贝叶斯。

P(Outcome|Multiple Evidence) = 
P(Evidence1|Outcome) * P(Evidence2|outcome) * ... * P(EvidenceN|outcome) * P(Outcome)
scaled by P(Multiple Evidence)

许多人选择将其记忆为:

                      P(Likelihood of Evidence) * Prior prob of outcome
P(outcome|evidence) = _________________________________________________
                                         P(Evidence)

观察一下这个等式:

  • 如果Prob(evidence|outcome)为1,则我们只是乘以1。
  • 如果Prob(some particular evidence|outcome)为0,则整个概率变为0。如果您看到有矛盾的证据,我们可以排除该结果。
  • 由于我们将所有内容除以P(Evidence),因此我们甚至可以不必计算它。
  • 通过乘以先验概率,我们的直觉是为了给更常见的结果赋予高概率,并为不太可能发生的结果赋予低概率。这些也被称为基础概率,它们是缩放预测概率的一种方法。

如何应用朴素贝叶斯来预测结果?

对于每个可能的结果,只需运行上面的公式。由于我们正在尝试分类,因此每个结果称为类别,它具有类标签。我们的任务是查看证据,考虑它是属于这个类还是那个类的可能性,并为每个实体分配一个标签。再次采用非常简单的方法:具有最高概率的类被声明为“获胜者”,并且该类标签被分配给那个证据组合。

水果示例

让我们通过一个例子来增加我们的理解力:OP要求一个“水果”识别示例。

假设我们有1000个水果的数据。它们是香蕉,橙子或其他水果。我们知道每种水果的三个特征:

  1. 是否长
  2. 是否甜
  3. 颜色是否为黄色。

这是我们的“训练集”。我们将使用它来预测我们遇到的任何新水果的类型。

Type           Long | Not Long || Sweet | Not Sweet || Yellow |Not Yellow|Total
             ___________________________________________________________________
Banana      |  400  |    100   || 350   |    150    ||  450   |  50      |  500
Orange      |    0  |    300   || 150   |    150    ||  300   |   0      |  300
Other Fruit |  100  |    100   || 150   |     50    ||   50   | 150      |  200
            ____________________________________________________________________
Total       |  500  |    500   || 650   |    350    ||  800   | 200      | 1000
             ___________________________________________________________________
我们可以预先计算有关我们的水果收藏的许多内容。 所谓的“先验”概率。 (如果我们不知道任何水果属性,这将是我们的猜测。)这些是我们的基础费率。
 P(Banana)      = 0.5 (500/1000)
 P(Orange)      = 0.3
 P(Other Fruit) = 0.2

"证据"的概率

p(Long)   = 0.5
P(Sweet)  = 0.65
P(Yellow) = 0.8

“Likelihood” 的概率

P(Long|Banana) = 0.8
P(Long|Orange) = 0  [Oranges are never long in all the fruit we have seen.]
 ....

P(Yellow|Other Fruit)     =  50/200 = 0.25
P(Not Yellow|Other Fruit) = 0.75

如何对水果进行分类?

假设我们拿到了一个未知水果的属性,需要对其进行分类。我们得知这个水果长、甜、黄色。它是香蕉吗?是橘子吗?还是其他水果?

我们可以逐一计算每种水果的概率,然后选择概率最高的那一类作为我们未知水果所属的类别(基于我们之前用过的1000个水果作为训练集的先验证据)。

P(Banana|Long, Sweet and Yellow) 
      P(Long|Banana) * P(Sweet|Banana) * P(Yellow|Banana) * P(banana)
    = _______________________________________________________________
                      P(Long) * P(Sweet) * P(Yellow)
                      
    = 0.8 * 0.7 * 0.9 * 0.5 / P(evidence)

    = 0.252 / P(evidence)


P(Orange|Long, Sweet and Yellow) = 0


P(Other Fruit|Long, Sweet and Yellow)
      P(Long|Other fruit) * P(Sweet|Other fruit) * P(Yellow|Other fruit) * P(Other Fruit)
    = ____________________________________________________________________________________
                                          P(evidence)

    = (100/200 * 150/200 * 50/200 * 200/1000) / P(evidence)

    = 0.01875 / P(evidence)

通过压倒性的比例(0.252 >> 0.01875),我们将这个甜的/长的/黄色的水果分类为可能是香蕉。

贝叶斯分类器为什么如此受欢迎?

看看它最终归结为什么:一些计数和乘法。我们可以预先计算所有这些术语,因此分类变得简单、快速和高效。

让 z = 1 / P(evidence)。 现在我们快速计算以下三个量。

P(Banana|evidence) = z * Prob(Banana) * Prob(Evidence1|Banana) * Prob(Evidence2|Banana) ...
P(Orange|Evidence) = z * Prob(Orange) * Prob(Evidence1|Orange) * Prob(Evidence2|Orange) ...
P(Other|Evidence)  = z * Prob(Other)  * Prob(Evidence1|Other)  * Prob(Evidence2|Other)  ...

将最高数字的类标签分配给它,并完成操作。

尽管名称如此,但朴素贝叶斯在某些应用程序中表现出色。文本分类是其中真正出色的领域之一。


17
感谢您提供非常清晰的解释!这是网上最好的解释之一。问题是:由于每个P(outcome / evidence)都乘以1 / z = p(evidence)(在水果案例中,这意味着每个结果实际上是仅基于先前证据计算的概率),那么是否可以说z对于朴素贝叶斯来说根本不重要?这也意味着,如果我们遇到一个长/甜/黄的水果,但它不是香蕉,它会被错误地分类。 - covariance
7
@E.Chow,你说得对,计算z对于朴素贝叶斯并不重要。(它是将概率缩放到0和1之间的一种方法。)请注意,z是所有已知证据概率的乘积。(它与先验不同,先验是类别的基础比率。)你是正确的:如果你找到了一个长/甜/黄的水果,但它不是香蕉,朴素贝叶斯会根据这个训练集错误地将它分类为香蕉。该算法是基于证据的“最佳概率猜测”,因此它会偶尔出现误分类。 - Ram Narasimhan
3
非常好的解释。我以前无法从学术论文和书籍中理解这个算法。因为晦涩难懂的解释似乎是被广泛接受的写作风格。现在一切都变得如此简单明了了。谢谢。 - Suat Atan PhD
2
谢谢,我更喜欢这个答案,比起教科书,它们试图使用大量的数学符号来迷惑我们,而不是真正地教授我们知识,但是您,先生,您是英雄! - Albert Gao
4
为什么概率不相加为1?在这个例子中,证据是0.26(500/100 * 650/1000 * 800/1000),所以最终P(香蕉|...)=0.252 / 0.26 = 0.969,而P(其他|...)=0.01875 / 0.26 = 0.072。它们加起来总共是1.04! - Mauricio
显示剩余21条评论

683
您的问题可以分为两部分,第一部分是您需要更好地理解朴素贝叶斯分类器,第二部分是对训练集的困惑。
通常,所有机器学习算法都需要进行训练,以便用于监督学习任务,如分类、预测等,或用于无监督学习任务,如聚类。
在训练阶段,算法会使用特定的输入数据集(训练集)进行学习,以便以后我们可以针对未知输入(它们以前从未见过)进行测试,在这种情况下,它们可以根据其学习进行分类或预测等操作(在有监督学习的情况下)。这就是大多数机器学习技术如神经网络、SVM、贝叶斯等的基础。
因此,在一般的机器学习项目中,您需要将输入集分成开发集(训练集+开发测试集)和测试集(或评估集)。请记住,您的基本目标是使您的系统学习并对开发集或测试集中以前从未见过的新输入进行分类。

测试集通常与训练集具有相同的格式。然而,测试集必须与训练语料库不同:如果我们简单地将训练集重复使用作为测试集,则仅仅记忆其输入而不学习如何推广到新示例的模型将会收到误导性高分。

一般来说,可以使用数据的70%作为训练集案例。同时,请记住将原始集合随机划分为训练集和测试集。

现在我回答你关于朴素贝叶斯的其他问题。

为了演示朴素贝叶斯分类的概念,考虑以下示例:

enter image description here

如上所述,对象可以被分类为GREENRED。我们的任务是在新情况出现时对其进行分类,即根据当前存在的对象确定它们属于哪个类别标签。
因为GREEN对象的数量是RED对象的两倍,所以合理地认为一个新情况(尚未观察到)是有两倍可能性成为GREEN而不是RED的成员。在贝叶斯分析中,这种信念被称为先验概率。先验概率基于以前的经验,本例中是GREENRED对象的百分比,并经常用于在实际发生之前预测结果。
因此,我们可以写成: GREEN的先验概率: 绿色对象的数量/总对象数 RED的先验概率: 红色对象的数量/总对象数 "由于总共有60个对象,其中40个是绿色的,20个是红色的,因此我们对类别成员资格的先验概率如下:
绿色的先验概率:40/60
红色的先验概率:20/60
制定了先验概率后,我们现在可以对新对象(下图中的白色圆圈)进行分类。由于对象被很好地聚集在一起,合理地假设在X附近有更多的绿色(或红色)对象,那么新案例属于该特定颜色的可能性就越大。为了衡量这种可能性,我们在X周围画一个圆圈,包括一些点(不考虑它们的类标签)。然后我们计算圆圈内属于每个类别标签的点数。从这里我们计算出可能性:"

enter image description here

enter image description here

从上面的插图可以清楚地看出,给定 GREEN 的情况下 X 的可能性比给定 RED 的情况下小,因为圆圈包含 1GREEN 对象和 3RED 对象。因此:

enter image description here

enter image description here

尽管先验概率表明X可能属于GREEN(因为GREEN的数量是RED的两倍),但似然性显示相反; X的类成员资格是RED(因为X附近有更多的RED对象而不是GREEN)。在贝叶斯分析中,最终分类是通过结合两种信息来源(即先验和似然)来产生后验概率,使用所谓的贝叶斯规则(以Rev. Thomas Bayes 1702-1761命名)。保留HTML标签。

enter image description here

最后,我们将X分类为RED,因为它的类成员资格达到了最大的后验概率。

42
上面这个算法不更像k-近邻算法吗? - Renaud
258
这个回答有点混淆——它混合了KNN(k最近邻)和朴素贝叶斯。 - Michal Illich
7
回答一直进行得很好,直到出现了可能性。所以@Yavar使用K最近邻算法来计算可能性。这种方法有多正确?如果是正确的,还有哪些其他方法可以用来计算可能性? - wrahool
1
你使用了圆圈作为可能性的示例。我读过关于高斯朴素贝叶斯的文章,其中似然是高斯的。这可以如何解释? - umair durrani
1
实际上,使用knn的答案是正确的。如果您不知道分布及其概率密度,则必须以某种方式找到它。这可以通过kNN或Kernels完成。我认为有一些东西缺失了。不过,您可以查看此演示文稿:http://courses.cs.tamu.edu/rgutier/cs790_w02/l9.pdf。 - C. S.
显示剩余8条评论

21
Naive Bayes是一种监督式机器学习算法,用于对数据集进行分类。它基于其先前的知识和独立性假设来预测事物。
他们称之为“naive”,因为它的假设(它假设数据集中的所有特征都是同等重要且相互独立的)非常乐观,并且在大多数实际应用中很少成立。
这是一种分类算法,用于为未知数据集做出决策。它基于贝叶斯定理,该定理描述了基于其先前知识的事件概率。
下面的图表显示了naive Bayes如何工作。

enter image description here

预测NB的公式:

enter image description here

如何使用朴素贝叶斯算法?

让我们举个例子,说明朴素贝叶斯是如何工作的。

步骤1:首先,我们需要找到概率表中“是”或“否”的可能性,如下图所示。

步骤2:找出每个类别的后验概率。

enter image description here

Problem: Find out the possibility of whether the player plays in Rainy condition?

P(Yes|Rainy) = P(Rainy|Yes) * P(Yes) / P(Rainy)

P(Rainy|Yes) = 2/9 = 0.222
P(Yes) = 9/14 = 0.64
P(Rainy) = 5/14 = 0.36

Now, P(Yes|Rainy) = 0.222*0.64/0.36 = 0.39 which is lower probability which means chances of the match played is low.

查看更多参考资料,请参考这些博客

参考 GitHub 存储库朴素贝叶斯示例


19

Ram Narasimhan在这里很好地解释了概念。以下是贝叶斯分类器的示例代码,作为一种替代解释。
它使用来自第351页的书籍的示例问题。
这是我们将要使用的数据集:
enter image description here
在上述数据集中,如果我们给出假设 = {"Age":'<=30', "Income":"medium", "Student":'yes' , "Creadit_Rating":'fair'},那么他会购买计算机或不会购买计算机的概率是多少。
下面的代码正好回答了这个问题。
只需创建一个名为new_dataset.csv的文件并粘贴以下内容。

Age,Income,Student,Creadit_Rating,Buys_Computer
<=30,high,no,fair,no
<=30,high,no,excellent,no
31-40,high,no,fair,yes
>40,medium,no,fair,yes
>40,low,yes,fair,yes
>40,low,yes,excellent,no
31-40,low,yes,excellent,yes
<=30,medium,no,fair,no
<=30,low,yes,fair,yes
>40,medium,yes,fair,yes
<=30,medium,yes,excellent,yes
31-40,medium,no,excellent,yes
31-40,high,yes,fair,yes
>40,medium,no,excellent,no

这里是代码,注释中解释了我们在这里做的一切![Python]

import pandas as pd 
import pprint 

class Classifier():
    data = None
    class_attr = None
    priori = {}
    cp = {}
    hypothesis = None


    def __init__(self,filename=None, class_attr=None ):
        self.data = pd.read_csv(filename, sep=',', header =(0))
        self.class_attr = class_attr

    '''
        probability(class) =    How many  times it appears in cloumn
                             __________________________________________
                                  count of all class attribute
    '''
    def calculate_priori(self):
        class_values = list(set(self.data[self.class_attr]))
        class_data =  list(self.data[self.class_attr])
        for i in class_values:
            self.priori[i]  = class_data.count(i)/float(len(class_data))
        print "Priori Values: ", self.priori

    '''
        Here we calculate the individual probabilites 
        P(outcome|evidence) =   P(Likelihood of Evidence) x Prior prob of outcome
                               ___________________________________________
                                                    P(Evidence)
    '''
    def get_cp(self, attr, attr_type, class_value):
        data_attr = list(self.data[attr])
        class_data = list(self.data[self.class_attr])
        total =1
        for i in range(0, len(data_attr)):
            if class_data[i] == class_value and data_attr[i] == attr_type:
                total+=1
        return total/float(class_data.count(class_value))

    '''
        Here we calculate Likelihood of Evidence and multiple all individual probabilities with priori
        (Outcome|Multiple Evidence) = P(Evidence1|Outcome) x P(Evidence2|outcome) x ... x P(EvidenceN|outcome) x P(Outcome)
        scaled by P(Multiple Evidence)
    '''
    def calculate_conditional_probabilities(self, hypothesis):
        for i in self.priori:
            self.cp[i] = {}
            for j in hypothesis:
                self.cp[i].update({ hypothesis[j]: self.get_cp(j, hypothesis[j], i)})
        print "\nCalculated Conditional Probabilities: \n"
        pprint.pprint(self.cp)

    def classify(self):
        print "Result: "
        for i in self.cp:
            print i, " ==> ", reduce(lambda x, y: x*y, self.cp[i].values())*self.priori[i]

if __name__ == "__main__":
    c = Classifier(filename="new_dataset.csv", class_attr="Buys_Computer" )
    c.calculate_priori()
    c.hypothesis = {"Age":'<=30', "Income":"medium", "Student":'yes' , "Creadit_Rating":'fair'}

    c.calculate_conditional_probabilities(c.hypothesis)
    c.classify()

输出:

Priori Values:  {'yes': 0.6428571428571429, 'no': 0.35714285714285715}

Calculated Conditional Probabilities: 

{
 'no': {
        '<=30': 0.8,
        'fair': 0.6, 
        'medium': 0.6, 
        'yes': 0.4
        },
'yes': {
        '<=30': 0.3333333333333333,
        'fair': 0.7777777777777778,
        'medium': 0.5555555555555556,
        'yes': 0.7777777777777778
      }
}

Result: 
yes  ==>  0.0720164609053
no  ==>  0.0411428571429

14

我尝试用一个例子来解释贝叶斯定理。

从社会中随机选择的一个人,他是吸烟者的概率是多少?

你可能回答10%,假设这是正确的。

现在,如果我说这个随机选出的人是男性并且15岁呢?

你可能会说是15%或20%,但为什么呢?

事实上,我们试图通过新的证据更新我们的初始猜测(P(吸烟者) vs. P(吸烟者 | 证据))。贝叶斯定理是将这两个概率联系起来的一种方法。

P(smoker | evidence) = P(smoker)* p(evidence | smoker)/P(evidence)

每一个证据都可能增加或降低这个机会。例如,他是男人这个事实可能会增加机会,前提是不吸烟者中男性的比例较低。

换句话说,成为男性必须是吸烟者而不是非吸烟者的指标。 因此,如果一项证据是某事物的指标,它就会增加机会。

但我们如何知道这是一个指标呢?

对于每个特征,您可以将其在给定条件下的普遍性(概率)与其单独的普遍性进行比较。(P(f | x) vs. P(f))。

P(smoker | evidence) / P(smoker) = P(evidence | smoker)/P(evidence)

例如,如果我们知道吸烟者中有90%是男性,仅凭此并不能确定男性是否是吸烟者的指标。例如,如果在社会中男性的比例也是90%,那么知道某人是男性就无法帮助我们 ((90%/ 90%) = 1。但是,如果男性在社会中占40%,但吸烟者中有90%是男性,那么知道某人是男性将增加成为吸烟者的可能性(90% / 40%) = 2.25,这将使最初的猜测(10%)增加2.25倍,即22.5%。

然而,如果在社会中男性的比例是95%,那么无论男性在吸烟者中的比例有多高(90%),知道某人是男性都会降低他成为吸烟者的可能性!(90% / 95%) = 0.95)

因此,我们有:

P(smoker | f1, f2, f3,... ) = P(smoker) * contribution of f1* contribution of f2 *... 
=
P(smoker)* 
(P(being a man | smoker)/P(being a man))*
(P(under 20 | smoker)/ P(under 20))

请注意,在这个公式中,我们假设男性20岁以下是独立的特征,所以我们将它们相乘,这意味着知道一个人年龄在20岁以下并不能影响猜测他是男还是女。但这不一定是真的,例如,也许在某个社会中大多数青少年都是男性...

如何在分类器中使用这个公式

分类器提供了一些特征(男性和年龄在20岁以下),必须决定他是否吸烟(这是两个类别)。它使用上述公式来计算在给定证据(特征)下每个类别的概率,并将具有最高概率的类别分配给输入。为了提供所需的概率(90%、10%、80%...),它使用训练集。例如,它统计训练集中的吸烟者人数,并发现他们占样本的10%。然后,对于吸烟者,检查他们中有多少男性或女性....有多少人超过20岁或年龄在20岁以下....换句话说,它尝试基于训练数据构建每个类别特征的概率分布。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接