教材-选必4-3.2 贝叶斯分类器

教材

3.2 贝叶斯分类器

人工智能领域的很多问题都属于如何让计算机学会对样本进行分类的问题。而机器学习中的许多分类算法都可以用来构造分类器,常用的有朴素贝叶斯、决策树、随机森林、逻辑回归、支持向量机和神经网络等。不过分类器有时候也会给出错误的结果,这时候就可以要求分类器给出一个最优的类别猜测结果,同时给出这个猜测的概率估计值。概率论是许多机器学习算法的基础,因此深刻理解概率论十分重要。

本节将从最简单的概率分类器开始,通过一些案例来学习构造朴素贝叶斯分类器(Naive Bayes Classifier)。之所以称之为“朴素”,是因为整个形式化过程中只有最原始、最简单的假设。我们还将充分利用Python的文本处理能力,构建一个垃圾邮件分类器,观察该分类器在真实的垃圾邮件数据集中的过滤效果。

3.2.1 朴素贝叶斯分类器

在概率统计理论中,条件概率是指事件A在另外一个事件B已经发生的条件下的发生概率,表示为[P(A|B)],读作“在B的条件下A发生的概率”。

贝叶斯(T.Bayes,约1702-1761),提出了下面的条件概率公式——贝叶斯公式:

$$P(A|B) = \frac{P(AB)}{P(B)} = \frac{P(B|A)P(A)}{P(B)}$$

其中,[P(AB)]代表A和B同时发生的概率,[P(B)]代表B发生的概率,[P(A|B)]代表在B发生的情况下A发生的概率。

观察

在现实生活中,我们经常要根据观测到的现象(特征数据)推测现象背后的结果。例如,我们看到草地湿了,需要判断是不是下雨导致的;今天股市的交易量大涨,需要判断是不是有新资金入场,还是存量资金博弈了一把;去医院体检,检查结果为阳性,是需要进一步检查,还是因为医院误诊;邮箱收到一封电子邮件,这封邮件是广告公司投放的垃圾邮件,还是从朋友那里发来的重要信件……朴素贝叶斯分类器可以利用历史数据的分布来推测一个最有可能的结果,使犯错误的概率最小化。

调查

以小组合作的形式,完成下述调查任务,并分小组进行汇报。
(1)调查日常生活中的哪些情境可以使用朴素贝叶斯的思想来做选择判断。
(2)通过网络搜索和文献查找的方式,了解朴素贝叶斯分类器的原理以及朴素贝叶斯在人工智能领域的典型应用案例。

下面我们通过一个例子来理解贝叶斯定理。某种疾病,年轻人得病的概率是0.5%,年长者如图3-5所示,列举了各种不同的得病情况,箭头附近的数字表示各种概率。例如,没患病检查结果却为阳性(误诊了)的概率是1%,没患病而且检查结果阴性的概率是99%。如果一个年轻人去医院体检,体检结果为阳性,那么这个人到底患病还是被误诊呢?

(图)

有的人可能会说,既然检查结果为阳性的人99%的概率会被确诊患病,那么比没病的概率要高吧?然而,如果一个年轻人的检查结果为阳性,真正得病的概率还要低。

现在我们来分析一下,假设人群中有20000人,按照如图3-5所示的患病概率,约18000人是正常的,约2000人患此病;在18000个健康人中,年轻人的概率为95%,检查结果为阳性的概率为1%,那么同时满足“年轻人”“检查结果为阳性”“无此病”的人数为18000×95%×1%=171(人);在2000个病人中,年轻人的概率是5%,检查结果为阳性的概率是99%。那么同时满足“年轻人”“患此病”“检查结果为阳性”的人数为2000×5%×99%=99(人)。如果我们现在只知道这个人是年轻人,而且检查结果呈阳性,那么他有可能是本身真的患病并且被检查出来的人,也有可能是误诊了的人。患病概率为$\frac{99}{99+171} \approx 36.7\%$。误诊概率为$\frac{171}{99+171} \approx 63.3\%$。显然,我们有更大的可能性相信他没有患病(所以现实生活中,医生会让我们多复诊几次)。

上述分析过程分别用到了特征条件独立假设、贝叶斯定理、后验概率最大化这几个知识点。

  1. 特征条件独立假设

我们的目的是通过“目前已知的数据”判断未知的结果。这个“目前已知的数据”被称为特征。在本节例子中,特征就是这个人“是否年轻”以及“检查结果是否为阳性”。这里我们要做一个重要的假设:在判断这个人有没有患病的时候,我们认为上述两个特征之间是独立的,即这个人“是否年轻”和“检查结果是否为阳性”之间没有联系。因此,随机抽取一个检查者,他“年轻”并且“检查结果为阳性”的概率就等于“年轻”的概率乘“检查结果为阳性”的概率。

上面这个假设就是条件独立假设。如果变量不满足独立性,则不可以将两者的概率相乘,比如“天空有云”的概率是0.5,“下雨”的概率是0.33,但“下雨”不能独立于“天空中有没有云”而存在,就不能得到“既有云又下雨”的概率为0.5×0.33这个结论。

  1. 贝叶斯定理

贝叶斯定理主要用于在给定特征数据的情况下,判定样本属于某个类别的概率。在下面的公式中,样本的数据用$X=x$表示,样本的类别属于某个类别用$Y=c_k$表示。

$$P(Y=c_k|X=x) = \frac{P(X=x|Y=c_k)P(Y=c_k)}{\sum P(X=x|Y=c_k)P(Y=c_k)}$$

在本节例子中,检查结果呈阳性的年轻人患病的概率:

$$P = \frac{A}{B} = \frac{99}{99+171} \approx 36.7\%$$

其中,A为真实得病的人中“检查为阳性”并且“年轻”的人数,B为人群中所有“检查结果为阳性”并且“年轻”的人数。这个公式就是贝叶斯定理的公式。

  1. 后验概率最大化

已知一个“年轻”人的“检查结果为阳性”,那么他有没有患病呢?我们只需要用贝叶斯公式计算,看看这个“年轻”并且“检查结果为阳性”的人到底是得病的概率更高,还是没得病的概率更高。这个就是后验概率最大化的直观解释。在本节的例子中,我们可以得出结论,检查结果为阳性也不意味着年轻人就得病了,但是为了保险起见,机器学习模型会根据这个概率来做出最优的判断。

3.2.2 朴素贝叶斯分类器的类型

在使用朴素贝叶斯分类器进行条件概率估计的时候,我们需要知道独立事件的先验概率。例如本节的例子直接告诉我们“人群中90%的人都无此病”这一先验概率。但是当分析其他事件的时候,可能会面临不同的特征(独立事件)分布。例如投掷一枚硬币,我们会假设任意一个点数朝上的先验概率=1/2。

特征分布的假设被称为朴素贝叶斯分类器的事件模型。下面我们了解一些常用的建模方法。对于文档分类(包括垃圾邮件过滤)这样的离散特征建模,多项式模型和伯努利模型很常用。

  1. 高斯模型

在处理实际数值这样的连续型变量时,通常会假设这些连续数值服从高斯分布。只需要估计训练数据的平均值和标准差。

假设训练集包含一个连续型的属性x,我们首先根据类别对数据进行分段,然后每个类别中x的均值和方差。设$\mu_e$为x中与类别c相关联值的均值,$\sigma_e^2$为x中与类关联值的方差。假设我们已经收集了一些观测值v,那么根据高斯分布公式,v的概率分布

$$p(x=v|c) = \frac{1}{\sqrt{2\pi}\sigma_c^2}e^{-\frac{(x-m)^2}{2\sigma_c^2}}$$

  1. 多项式模型

在多项式模型中,样本(特征向量)表示特定事件发生的次数。这一模型通常用来分类,特征是单词,值是单词的出现次数。用$p_c$表示事件i发生的概率,其中$x_i$表示第i个词汇有没有出现在文档中,那么这篇文档属于类别c的可能性

$p(x=v|c) = \frac{(\sum_i x_i)!}{\prod_{i=1}^{n}!} \Pi p_{c_i}$

  1. 伯努利模型

在伯努利模型中,每个特征的取值是布尔型的,即true和false,或者1和0。和多项式模型一样,这个模型在文本分类中也非常流行,就是看某个特征有没有在文档中出现。如果$x_i$表示第i个词汇有没有出现在文档中,那么这篇文档属于类别c的可能性

$$ p(x=v|c) = \prod_{i=1}^{n} p_{c_i}^{x_i}(1-p_{c_i})^{(1-x_i)}$$

其中,$p_{c_i}$表示类别为c的文档中出现词汇$x_i$的概率。这个模型通常用于短文本分类。

3.2.3 朴素贝叶斯分类器的应用

朴素贝叶斯分类器有许多有意思的应用。例如在线社区的留言板中,为了不影响社区的发展,屏蔽侮辱性的言论是很有必要的。如果某条留言使用了负面或侮辱性的语言,该留言将被标识为内容不当。因此,利用朴素贝叶斯分类器构建一个快速过滤器来过滤这类内容,是一个很常见的需求。

信息时代,我们每天会面对大量信息,如果不根据重要性设定优先级分别处理,我们将会耗费大量精力。因此对垃圾邮件或垃圾短信进行智能过滤非常重要。下面我们将利用朴素贝叶斯分类器,用Python构建一个垃圾邮件过滤器。

构建机器学习模型首先得有足够的样本数据进行训练,我们利用网络上开源的中文邮件数据集,提取其中的5000封正常邮件和5000封垃圾邮件进行训练。通过解析所有邮件,提取并计算每个词语在正常邮件和垃圾邮件中的出现频率,基于贝叶斯原理推断这封邮件是否需要过滤。

正常邮件示例:

发信人:pbldq(dp),信区:LostFound

标题:[报失]IC卡

请尽可能详细地描述您丢失物品的特征:IC卡。

姓名:丁强,学号:2018210502。

您丢失该物品大致的时间是?8月24日上午9时左右。您丢失该物品大致的地点是?清华大学校医院体检处。如果有人拾获,如何和您联系?电话:62779634。[补充]表达一下您焦急的心情或感谢的方式^-^祝您好运:谢谢!

垃圾邮件示例:

有情之人,天天是节。一句寒暖,一线相喧;一句叮咛,一笺相传;一份相思,一心相盼;一份爱意,一生相恋。

xxx在此祝大家七夕情人节快乐!xxx友情提示:2018年七夕情人节——8月17日,别忘了给她(他)送祝福哦!

为了更好地体验邮件收发过程,我们可以利用TCP通信简单模拟邮件传输协议,用客户端向服务器端通信的过程模拟邮件发送的过程,用服务器端接收消息的过程模拟邮件收信的过程。所以朴素贝叶斯分类器会在服务器端运行。

实践

打开并运行server.py程序,建立TCP通信服务器端,模拟邮件的接收。其中垃圾邮件分类器建立的关键过程如下:
(1)训练分类器前,要先将邮件中的句子分成一个个词汇,jieba模块为我们提供了方便的汉语分词功能。

import jieba
res = list(set(list(jieba.cut(email))))
wordlist[dirt].extend(res)

(2)使用collections统计模块分别计算正常(normal)邮件和垃圾(trash)邮件的词占邮件总词汇数的比例,计算该词的$P(s|w)$,也就是在该词影响下,该邮件是垃圾邮件的概率

$$P(s|w) = \frac{P(w|s)P(s)}{P(w|s)P(s) + P(s|h)P(h)}$$

当收到一封未知邮件时,在不确定的前提下,我们假定它是垃圾邮件和正常邮件的概率各为50%,即$P(s) = P(n) = 50\%$。

# 导入sklearn模块的朴素贝叶斯分类器高斯模型GaussianNB

from sklearn.naive_bayes import GaussianNB

# 创建分类器
clf = GaussianNB()

# 训练分类器
X = features_train
Y = labels_train
clf.fit(X, Y)

(3)提取该邮件中出现概率[ P(s|w) ]最高的15个词,联合概率

$$P = \frac{P_1 P_2 \cdots P_{15}}{(1 - P_1)(1 - P_2) \cdots (1 - P_{15})}$$

设定阈值P>0.9为垃圾邮件,P<0.9为正常邮件。


项目实施

实验结果表明,朴素贝叶斯垃圾邮件分类器在该数据集上达到了近96%的准确率。但即使这样,垃圾邮件分类器还可能将正常的邮件当作垃圾邮件过滤掉。通过继续调整模型的参数,垃圾邮件分类器还可以达到更好的效果。

为了测试垃圾邮件分类器能否工作,运行client.py程序,建立与服务器端的连接后,发送想要传输的内容,看看服务器端收到消息后会给出什么样的判断。

各小组根据项目选题及拟订的项目方案,结合本节所学知识,剖析贝叶斯分类器算法。

  1. 运行配套学习资源包中的程序,体验朴素贝叶斯分类器的应用。
  2. 运行配套学习资源包中的程序,调整朴素贝叶斯垃圾邮件分类器的参数,提高垃圾邮件分类能力。
发表新评论