其他分享
首页 > 其他分享> > 朴素贝叶斯笔记

朴素贝叶斯笔记

作者:互联网

贝叶斯公式

贝叶斯公式就是采用贝叶斯准则来计算条件概率,它告诉我们计算时交换条件概率中的条件与结果:
P(YX)=P(XY)P(Y)P(X)P(Y|X)=\frac{P(X|Y)P(Y)}{P(X)}P(Y∣X)=P(X)P(X∣Y)P(Y)​
P(YX)P(Y|X)P(Y∣X) 不能通过直接观测来得到结果,而P(XY)P(X|Y)P(X∣Y) 却容易通过直接观测得到结果,就可以通过贝叶斯公式从间接地观测对象去推断不可直接观测的对象的情况。

而贝叶斯公式又是根据联合概率公式推导而来的:
P(Y,X)=P(X)P(YX)=P(Y)P(XY)P(Y,X)=P(X)P(Y|X)=P(Y)P(X|Y)P(Y,X)=P(X)P(Y∣X)=P(Y)P(X∣Y)
其中P(YX)P(Y|X)P(Y∣X)叫后验概率,也就是我们想得到的,P(Y)P(Y)P(Y)叫先验概率,是可以事先依据统计计算出的,P(Y,X)P(Y,X)P(Y,X)叫联合概率
即联合概率链规则(chain rule):每个元素出现的概率都与它之前的元素有关联
P(x1,x2,x3,x4,x5,,xn)=P(x1)P(x2x1)P(x3x1,x2)...P(xnx1,x2,...,xn1)P(x_1,x_2,x_3,x_4,x_5,…,x_n)=P(x_1)P(x_2|x_1)P(x_3|x_1,x_2)...P(x_n|x_1,x_2,...,x_{n-1})P(x1​,x2​,x3​,x4​,x5​,…,xn​)=P(x1​)P(x2​∣x1​)P(x3​∣x1​,x2​)...P(xn​∣x1​,x2​,...,xn−1​)

用机器学习的视角理解贝叶斯公式

在机器学习的视角下,我们把 X 理解成具有某特征的向量,把 Y 理解成类别标签。在最简单的二分类问题(是与否判定)下,我们将 Y 理解成属于某类的标签。于是贝叶斯公式就变形成了下面的样子:
P()=P()P()P()P(“属于某类”|“具有某特征”)=\frac{P(“具有某特征”|“属于某类”)P(“属于某类”)}{P(“具有某特征”)}P(“属于某类”∣“具有某特征”)=P(“具有某特征”)P(“具有某特征”∣“属于某类”)P(“属于某类”)​
贝叶斯方法把计算“具有某特征的条件下属于某类”的概率转换成需要计算“属于某类的条件下具有某特征”的概率,而后者获取方法就简单多了,我们只需要找到一些包含已知特征标签的样本,即可进行训练。而样本的类别标签都是明确的,所以贝叶斯方法在机器学习里属于有监督学习方法。

这里再补充一下,一般"先验概率"、"后验概率"是相对出现的,比如 P(Y) 与 P(Y|X) 是关于 Y 的先验概率与后验概率, P(X) 与 P(X|Y) 是关于 X 的先验概率与后验概率。

举个例子,以垃圾邮件识别为例,假设我们有垃圾邮件和正常邮件各1万封作为训练集。需要判断以下这个邮件是否属于垃圾邮件:

“我司可办理正规发票(保真)17%增值税发票点数优惠!”

也就是判断概率 P(“垃圾邮件”|“我司可办理正规发票(保真)17%增值税发票点数优惠!”) 是否大于1/2。直观来看,要计算此概率就是统计出正常邮件和垃圾邮件中出现这句话的次数,具体如下:
P(17%)P(“垃圾邮件”|“我司可办理正规发票(保真)17\%增值税发票点数优惠!”)P(“垃圾邮件”∣“我司可办理正规发票(保真)17%增值税发票点数优惠!”)
=+ =\frac{垃圾邮件中出现这句话的次数}{垃圾邮件中出现这句话的次数+正常邮件中出现这句话的次数}=垃圾邮件中出现这句话的次数+正常邮件中出现这句话的次数垃圾邮件中出现这句话的次数​

但这么做并不可取,因为训练集是有限的,而句子的可能性则是无限的。所以覆盖所有句子可能性的训练集是不存在的。假设要对一个新句子进行归类预测,而这个新句子从未在训练集出现过,那岂不就是无法对其进行分类判断。

于是,我们可以不拿句子作为特征,而是拿句子里面的词语(组合)作为特征去考虑。比如“正规发票”可以作为一个单独的词语,“增值税”也可以作为一个单独的词语等等。

句子“我司可办理正规发票,17%增值税发票点数优惠!”就可以变成
(“我”,“司”,“可”,“办理”,“正规发票”,“保真”,“增值税”,“发票”,“点数”,“优惠”))。

我们观察(“我”,“司”,“可”,“办理”,“正规发票”,“保真”,“增值税”,“发票”,“点数”,“优惠”),这可以理解成一个向量:向量的每一维度都表示着该特征词在文本中的特定位置存在。

因此贝叶斯公式就变成了:
P(,,,,,,,,,)P(“垃圾邮件”|(“我”,“司”,“可”,“办理”,“正规发票”,“保真”,“增值税”,“发票”,“点数”,“优惠”))P(“垃圾邮件”∣(“我”,“司”,“可”,“办理”,“正规发票”,“保真”,“增值税”,“发票”,“点数”,“优惠”))
=P(,,,,,,,,,)""P()P(,,,,,,,,,))=\frac{P((“我”,“司”,“可”,“办理”,“正规发票”,“保真”,“增值税”,“发票”,“点数”,“优惠”)|"垃圾邮件")P(“垃圾邮件”)}{P((“我”,“司”,“可”,“办理”,“正规发票”,“保真”,“增值税”,“发票”,“点数”,“优惠”)) }=P((“我”,“司”,“可”,“办理”,“正规发票”,“保真”,“增值税”,“发票”,“点数”,“优惠”))P((“我”,“司”,“可”,“办理”,“正规发票”,“保真”,“增值税”,“发票”,“点数”,“优惠”)∣"垃圾邮件")P(“垃圾邮件”)​
P(,,,,,,,,,)P(“正常邮件”|(“我”,“司”,“可”,“办理”,“正规发票”,“保真”,“增值税”,“发票”,“点数”,“优惠”))P(“正常邮件”∣(“我”,“司”,“可”,“办理”,“正规发票”,“保真”,“增值税”,“发票”,“点数”,“优惠”))
=P(,,,,,,,,,)""P()P(,,,,,,,,,))=\frac{P((“我”,“司”,“可”,“办理”,“正规发票”,“保真”,“增值税”,“发票”,“点数”,“优惠”)|"正常邮件")P(“正常邮件”)}{P((“我”,“司”,“可”,“办理”,“正规发票”,“保真”,“增值税”,“发票”,“点数”,“优惠”)) }=P((“我”,“司”,“可”,“办理”,“正规发票”,“保真”,“增值税”,“发票”,“点数”,“优惠”))P((“我”,“司”,“可”,“办理”,“正规发票”,“保真”,“增值税”,“发票”,“点数”,“优惠”)∣"正常邮件")P(“正常邮件”)​

条件独立假设

以下引入一个粗暴的假设

概率 P((“我”,“司”,“可”,“办理”,“正规发票”,“保真”,“增值税”,“发票”,“点数”,“优惠”)|“垃圾邮件”) 依旧不够好求,我们引进一个很朴素的近似。为了让公式显得更加紧凑,我们令字母S表示“垃圾邮件”,令字母H表示“正常邮件”。近似公式如下:
P(,,,,,,,,,)SP((“我”,“司”,“可”,“办理”,“正规发票”,“保真”,“增值税”,“发票”,“点数”,“优惠”)|S)P((“我”,“司”,“可”,“办理”,“正规发票”,“保真”,“增值税”,“发票”,“点数”,“优惠”)∣S)
=P(S×P(S×P(S×P(S×P(S=P(“我”|S)×P(“司”|S)×P(“可”|S)×P(“办理”|S)×P(“正规发票”|S)=P(“我”∣S)×P(“司”∣S)×P(“可”∣S)×P(“办理”∣S)×P(“正规发票”∣S)
×P(S×P(S×P(S×P(S×P(S)×P(“保真”|S)×P(“增值税”|S)×P(“发票”|S)×P(“点数”|S)×P(“优惠”|S)×P(“保真”∣S)×P(“增值税”∣S)×P(“发票”∣S)×P(“点数”∣S)×P(“优惠”∣S)

上述公式就是假设每个特征词在特定类别下的出现,相互之间是独立不相关的,这就是条件独立假设

于是我们就只需要比较以下两个式子的大小来作出分类判断:
C=P(S)P(S)P(S)P(S)P(S)C = P(“我”|S)P(“司”|S)P(“可”|S)P(“办理”|S)P(“正规发票”|S)C=P(“我”∣S)P(“司”∣S)P(“可”∣S)P(“办理”∣S)P(“正规发票”∣S)
×P(S)P(S)P(S)P(S)P(S)P()×P(“保真”|S)P(“增值税”|S)P(“发票”|S)P(“点数”|S)P(“优惠”|S)P(“垃圾邮件”)×P(“保真”∣S)P(“增值税”∣S)P(“发票”∣S)P(“点数”∣S)P(“优惠”∣S)P(“垃圾邮件”)

C=P(H)P(H)P(H)P(H)P(H)\overline{C}=P(“我”|H)P(“司”|H)P(“可”|H)P(“办理”|H)P(“正规发票”|H)C=P(“我”∣H)P(“司”∣H)P(“可”∣H)P(“办理”∣H)P(“正规发票”∣H)
×P(H)P(H)P(H)P(H)P(H)P()×P(“保真”|H)P(“增值税”|H)P(“发票”|H)P(“点数”|H)P(“优惠”|H)P(“正常邮件”)×P(“保真”∣H)P(“增值税”∣H)P(“发票”∣H)P(“点数”∣H)P(“优惠”∣H)P(“正常邮件”)

这样处理后式子中的每一项都特别好求!只需要分别统计各类邮件中该关键词出现的概率就可以了,如:
P(S=P(“发票”|S)=\frac{垃圾邮件中所有“发票”的次数}{垃圾邮件中所有词语的次数}P(“发票”∣S)=垃圾邮件中所有词语的次数垃圾邮件中所有“发票”的次数​

统计次数非常方便,而且样本数量足够大,算出来的概率比较接近真实。于是垃圾邮件识别的问题就可解了。

朴素贝叶斯(Naive Bayes)究竟“朴素”在何处?

加上条件独立假设的贝叶斯方法就是朴素贝叶斯方法(Naive Bayes)。将句子(“我”,“司”,“可”,“办理”,“正规发票”) 中的 (“我”,“司”)与(“正规发票”)调换一下顺序,就变成了一个新的句子(“正规发票”,“可”,“办理”, “我”, “司”)。新句子与旧句子的意思完全不同。但由于乘法交换律,朴素贝叶斯方法中算出来二者的条件概率完全一样!计算过程如下:
P(,,,,S)=P(S)P(S)P(S)P(S)P(S)=P(S)P(S)P(S)P(S)P(S=P(,,,,S)P((“我”,“司”,“可”,“办理”,“正规发票”)|S)\\=P(“我”|S)P(“司”|S)P(“可”|S)P(“办理”|S)P(“正规发票”|S) \\=P(“正规发票”|S)P(“可”|S)P(“办理”|S)P(“我”|S)P(“司”|S)\\=P((“正规发票”,“可”,“办理”, “我”, “司”)|S)P((“我”,“司”,“可”,“办理”,“正规发票”)∣S)=P(“我”∣S)P(“司”∣S)P(“可”∣S)P(“办理”∣S)P(“正规发票”∣S)=P(“正规发票”∣S)P(“可”∣S)P(“办理”∣S)P(“我”∣S)P(“司”∣S)=P((“正规发票”,“可”,“办理”,“我”,“司”)∣S)

也就是说,在朴素贝叶斯眼里,“我司可办理正规发票”与“正规发票可办理我司”完全相同。朴素贝叶斯失去了词语之间的顺序信息。这就相当于把所有的词汇扔进到一个袋子里随便搅和,贝叶斯都认为它们一样。因此这种情况也称作词袋子模型(bag of words)

处理重复词语的方式

我们之前的垃圾邮件向量(“我”,“司”,“可”,“办理”,“正规发票”,“保真”,“增值税”,“发票”,“点数”,“优惠”),其中每个词都不重复。而这在现实中其实很少见。因为如果文本长度增加,或者分词方法改变,必然会有许多词重复出现,因此需要对这种情况进行进一步探讨。比如以下这段邮件:

“代开发票。增值税发票,正规发票。” 分词后为向量: (“代开”,“发票”,“增值税”,“发票”,“正规”,“发票”)

其中“发票”重复出现了三次。

多项式模型

如果我们考虑重复词语的情况,也就是说,重复的词语我们视为其出现多次,直接按条件独立假设的方式推导,则有
P(,,,,,)S=P(S)P(S)P(S)P(S)P(S)P(S=P(S)P3(S)P(S)P(S)P((“代开”,“发票”,“增值税”,“发票”,“正规”,“发票”)|S\\=P(“代开””|S)P(“发票”|S)P(“增值税”|S)P(“发票”|S)P(“正规”|S)P(“发票”|S)\\=P(“代开””|S)P^3(“发票”|S)P(“增值税”|S)P(“正规”|S)P((“代开”,“发票”,“增值税”,“发票”,“正规”,“发票”)∣S=P(“代开””∣S)P(“发票”∣S)P(“增值税”∣S)P(“发票”∣S)P(“正规”∣S)P(“发票”∣S)=P(“代开””∣S)P3(“发票”∣S)P(“增值税”∣S)P(“正规”∣S)注意这一项:P3(SP^3(“发票”|S)P3(“发票”∣S)

在统计计算P(“发票”|S)时,每个被统计的垃圾邮件样本中重复的词语也统计多次。
P(S=P(“发票”|S)=\frac{每封垃圾邮件中出现“发票”的次数的总和}{每封垃圾邮件中所有词出现次数(计算重复次数)的总和}P(“发票”∣S)=每封垃圾邮件中所有词出现次数(计算重复次数)的总和每封垃圾邮件中出现“发票”的次数的总和​

这个多次出现的结果,出现在概率的指数/次方上,因此这样的模型叫作多项式模型

伯努利模型

另一种更加简化的方法是将重复的词语都视为其只出现1次
P(,,,,,S)=P(S)P(S)P(S)P(SP((“代开”,“发票”,“增值税”,“发票”,“正规”,“发票”)|S)\\=P(“发票”|S)P(“代开””|S)P(“增值税”|S)P(“正规”|S)P((“代开”,“发票”,“增值税”,“发票”,“正规”,“发票”)∣S)=P(“发票”∣S)P(“代开””∣S)P(“增值税”∣S)P(“正规”∣S)
统计计算P(SP(“词语”|S)P(“词语”∣S)时也是如此。
P(S=P(“发票”|S)=\frac{出现“发票”的垃圾邮件的封数}{每封垃圾邮件中所有词出现次数(出现了只计算一次)的总和}P(“发票”∣S)=每封垃圾邮件中所有词出现次数(出现了只计算一次)的总和出现“发票”的垃圾邮件的封数​

这样的模型叫作伯努利模型(又称为二项独立模型)。这种方式更加简化与方便。当然它丢失了词频的信息,因此效果可能会差一些。

浅谈平滑技术

我们来说个问题,比如在预测以下独立条件假设的概率:
P(,,,,S)P((“我”,“司”,“可”,“办理”,“正规发票”)|S)P((“我”,“司”,“可”,“办理”,“正规发票”)∣S)
=P(S)P(S)P(S)P(S)P(S)=P(“我”|S)P(“司”|S)P(“可”|S)P(“办理”|S)P(“正规发票”|S)=P(“我”∣S)P(“司”∣S)P(“可”∣S)P(“办理”∣S)P(“正规发票”∣S)

我们扫描一下训练集,发现“正规发票”这个词从出现过!于是 P(“正规发票”|S)=0 …问题严重了,整个概率都变成0了!朴素贝叶斯方法面对一堆0,很凄惨地失效了…更残酷的是这种情况其实很常见,因为哪怕训练集再大,也可能有覆盖不到用来测试的句子中的词语。

为了解决这样的问题,一种分析思路就是直接不考虑这样的词语,但这种方法就相当于默认给P(“正规发票”|S)赋值为1。其实效果不太好,大量的统计信息给浪费掉了。我们进一步分析,既然可以默认赋值为1,为什么不能默认赋值为一个很小的数?这就是平滑技术的基本思路,依旧保持着一贯的作风,朴实/土但是直接而有效。

对于伯努利模型,P(“正规发票”|S)的一种平滑算法是:
P(S=+1+2P(“正规发票”|S)=\frac{出现“正规发票”的垃圾邮件的封数+1}{每封垃圾邮件中所有词出现次数(出现了只计算一次)的总和+2}P(“正规发票”∣S)=每封垃圾邮件中所有词出现次数(出现了只计算一次)的总和+2出现“正规发票”的垃圾邮件的封数+1​

对于多项式模型,P(“正规发票”| S)的一种平滑算法是:
P(S=+1+P(“正规发票”|S)=\frac{每封垃圾邮件中出现“正规发票”的次数的总和+1}{每封垃圾邮件中所有词出现次数(计算重复次数)的总和+被统计的词表的词语数量}P(“正规发票”∣S)=每封垃圾邮件中所有词出现次数(计算重复次数)的总和+被统计的词表的词语数量每封垃圾邮件中出现“正规发票”的次数的总和+1​

平滑技术都是给未出现在训练集中的词语一个估计的概率,而相应地调低其他已经出现的词语的概率。平滑技术是因为数据集太小而产生的现实需求。如果数据集足够大,平滑技术对结果的影响将会变小。

实际工程的技巧

取对数

我们提到用来识别垃圾邮件的方法是比较以下两个概率的大小(字母S表示“垃圾邮件”,字母H表示“正常邮件”):
C=P(S)P(S)P(S)P(S)P(S)×P(S)P(S)P(S)P(S)P(S)P()C = P(“我”|S)P(“司”|S)P(“可”|S)P(“办理”|S)P(“正规发票”|S)\\ ×P(“保真”|S)P(“增值税”|S)P(“发票”|S)P(“点数”|S)P(“优惠”|S)P(“垃圾邮件”)C=P(“我”∣S)P(“司”∣S)P(“可”∣S)P(“办理”∣S)P(“正规发票”∣S)×P(“保真”∣S)P(“增值税”∣S)P(“发票”∣S)P(“点数”∣S)P(“优惠”∣S)P(“垃圾邮件”)

C=P(H)P(H)P(H)P(H)P(H)×P(H)P(H)P(H)P(H)P(H)P()\overline{C}=P(“我”|H)P(“司”|H)P(“可”|H)P(“办理”|H)P(“正规发票”|H)\\ ×P(“保真”|H)P(“增值税”|H)P(“发票”|H)P(“点数”|H)P(“优惠”|H)P(“正常邮件”)C=P(“我”∣H)P(“司”∣H)P(“可”∣H)P(“办理”∣H)P(“正规发票”∣H)×P(“保真”∣H)P(“增值税”∣H)P(“发票”∣H)P(“点数”∣H)P(“优惠”∣H)P(“正常邮件”)

但这里进行了很多乘法运算,计算的时间开销比较大,而且程序会下溢出或者得到不正确的答案(用 Python 尝试相乘许多很小的数,最后四舍五入后会得到 0),尤其是对于篇幅比较长的邮件。如果能把这些乘法变成加法则方便得多。刚好数学中的对数函数log就可以实现这样的功能。两边同时取对数(本文统一取底数为2),则上面的公式变为:
logC=logP(S)+logP(S)+logP(S)+logP(S)+logP(S)+logP(S)+logP(S)+logP(S)+logP(S)+logP(S)+logP()log{C} = log{P(“我”|S)}+log{P(“司”|S)}+log{P(“可”|S)}+log{P(“办理”|S)}+log{P(“正规发票”|S)}\\+log{P(“保真”|S)}+log{P(“增值税”|S)}+log{P(“发票”|S)}+log{P(“点数”|S)}+log{P(“优惠”|S)}+log{P(“垃圾邮件”)}logC=logP(“我”∣S)+logP(“司”∣S)+logP(“可”∣S)+logP(“办理”∣S)+logP(“正规发票”∣S)+logP(“保真”∣S)+logP(“增值税”∣S)+logP(“发票”∣S)+logP(“点数”∣S)+logP(“优惠”∣S)+logP(“垃圾邮件”)


logC=logP(H)+logP(H)+logP(H)+logP(H)+logP(H)+logP(H)+logP(H)+logP(H)+logP(H)+logP(H)+logP()log{\overline{C}}=log{P(“我”|H)}+log{P(“司”|H)}+log{P(“可”|H)}+log{P(“办理”|H)}+log{P(“正规发票”|H)}\\+log{P(“保真”|H)}+log{P(“增值税”|H)}+log{P(“发票”|H)}+log{P(“点数”|H)}+log{P(“优惠”|H)}+log{P(“正常邮件”)}logC=logP(“我”∣H)+logP(“司”∣H)+logP(“可”∣H)+logP(“办理”∣H)+logP(“正规发票”∣H)+logP(“保真”∣H)+logP(“增值税”∣H)+logP(“发票”∣H)+logP(“点数”∣H)+logP(“优惠”∣H)+logP(“正常邮件”)

虽然做对数运算也会花时间,但这样处理后,在训练阶段直接计算各个词的类别条件概率logPlog{P}logP,然后把他们存在一张大的hash表里。在测试阶段对一个新句子作预测判断的时候,具体是判断各个特征词xi在不在标签yi对应的单词条件概率字典里,在的话就直接提取hash表中已经计算好的对数概率值,不在的话就用默认概率值(平滑技术),然后相加即可。这样使得判断所需要的计算时间被转移到了训练阶段,实际预测运行的时候速度就比之前快得多,这可不止几个数量级的提升。

贝叶斯方法的思维方式

再看一眼贝叶斯公式:
P(YX)=P(XY)P(Y)P(X)P(Y|X)=\frac{P(X|Y)P(Y)}{P(X)}P(Y∣X)=P(X)P(X∣Y)P(Y)​
先不考虑先验概率P(Y)P(X)P(Y)与P(X)P(Y)与P(X),观察两个后验概率P(YX)P(XY)P(Y|X)与P(X|Y)P(Y∣X)与P(X∣Y),可见贝叶斯公式能够揭示两个相反方向的条件概率之间的转换关系。

P(YX)P(Y|X)P(Y∣X) 不能通过直接观测来得到结果,而P(XY)P(X|Y)P(X∣Y) 却容易通过直接观测得到结果,就可以通过贝叶斯公式从间接地观测对象去推断不可直接观测的对象的情况

以垃圾邮件识别为例,基于邮件的文本内容判断其属于垃圾邮件的概率不好求(不可通过直接观测、统计得到),但是基于已经搜集好的垃圾邮件样本,去统计(直接观测)其文本内部各个词语的概率却非常方便。这就可以用贝叶斯方法。

引申一步,基于样本特征去判断其所属标签的概率不好求,但是基于已经搜集好的打上标签的样本(有监督),却可以直接统计属于同一标签的样本内部各个特征的概率分布。因此贝叶斯方法的理论视角适用于一切分类问题的求解。

总结

我们找了个最简单常见的例子:垃圾邮件识别,说明了一下朴素贝叶斯进行文本分类的思路过程。基本思路是先区分好训练集与测试集,对文本集合进行分词、去除标点符号等特征预处理的操作,然后使用条件独立假设,将原概率转换成词概率乘积,再进行后续的处理。

贝叶斯公式 + 条件独立假设 = 朴素贝叶斯方法

基于对重复词语在训练阶段的处理,我们相应的有伯努利模型和多项式模型。在测试阶段,如果训练样本集合太小导致新句子的某些词语并未出现在词表中,我们可以采用平滑技术对其概率给一个估计值,当然前提在训练阶段对各个特征词的条件概率的计算也要采取平滑计算公式。



参考: https://blog.csdn.net/han_xiaoyang/article/details/50616559

标签:logP,保真,笔记,正规,垃圾邮件,发票,贝叶斯,朴素,增值税
来源: https://blog.csdn.net/u012369535/article/details/97646935