用朴素贝叶斯做垃圾邮件分类&demo

贝叶斯公式

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

全概公式

P(A)=\sum_{i=1}^{N}P(A|B_i)P(B_i)

思路和实现

最终的目标:对于一封邮件,分词得到w_1, w_2, ..., w_n,我们需要求出给定w_1, w_2, ..., w_n的条件下,这封邮件是垃圾邮件的概率,即求出P(s|w_1, w_2, ..., w_n)。这里s表示是垃圾邮件(spam)。

根据贝叶斯公式:P(s|w_1, w_2, ..., w_n)=\frac{P(w_1, w_2, ..., w_n|s)P(s)}{P(w_1, w_2, ..., w_n)}

根据全概公式,上式=\frac{P(w_1, w_2, ..., w_n|s)P(s)}{P(w_1, w_2, ..., w_n|s)P(s)+P(w_1, w_2, ..., w_n|n)P(n)},这里n表示是正常邮件(noraml)。

令先验概率P(s)=P(n)=0.5,因此上式=\frac{P(w_1, w_2, ..., w_n|s)}{P(w_1, w_2, ..., w_n|s)+P(w_1, w_2, ..., w_n|n)}

根据朴素贝叶斯的独立假设,上式=\frac{\prod^{n}_{i=1}P(w_i|s)}{\prod^{n}_{i=1}P(w_i|s)+\prod^{n}_{i=1}P(w_i|n)},记为式1。

至此,我们很容易统计出P(w_i|s)P(w_i|n),比如全部的垃圾邮件共计1000封,其中w_k出现800次,则P(w_k|s)=0.8。但是如果这样统计,由于词数量很多,代入式1后,就会有很多小于1的小数连乘,结果趋于零,无法计算。因此式1需要继续推导。

根据贝叶斯公式:P(w_i|s)=\frac{P(s|w_i)P(w_i)}{P(s)},把这个带入到式1中,可以得到\frac{\prod^{n}_{i=1}P(s|w_i)}{\prod^{n}_{i=1}P(s|w_i)+\prod^{n}_{i=1}P(n|w_i)}

由于在w_i出现的条件下,要么是垃圾邮件,要么不是垃圾邮件,即P(s|w_i)+P(n|w_i)=1,则上式=\frac{\prod^{n}_{i=1}P(s|w_i)}{\prod^{n}_{i=1}P(s|w_i)+\prod^{n}_{i=1}(1-P(s|w_i))}

至此,我们只需要在训练集中统计出P(s|w_i),然后对于被判定邮件的w_1, w_2, ..., w_n,取出最大的前若干个P(s|w_i)带入到上式即可进行判定是不是垃圾邮件了,这样解决了小数连乘趋于0的问题。

接下来看下如何统计P(s|w_i)

上文已经介绍了如何统计出P(w_i|s)P(w_i|n),有了这两个,就可以计算P(s|w_i)了。

根据贝叶斯公式:P(s|w_i)=\frac{P(w_i|s)P(s)}{P(w_i)}

根据全概公式,上式=\frac{P(w_i|s)P(s)}{P(w_i|s)P(s)+P(w_i|n)P(n)}=\frac{p(w_i|s)}{P(w_i|s)+P(w_i|n)}

至此,可以写代码统计出P(w_i|s)P(w_i|n),然后进行判定了。如果被判定的邮件中,有些词没有在训练集的垃圾邮件中出现。则令P(w_i|s)=0.01,同理,要是在训练集的正常邮件中没有出现,则令P(w_i|n)=0.01,如果两种邮件中都没出现过,则令P(s|w_i)=0.4。这些设定都是经验值。

代码实现和数据集

由于数据是中文的,因此用到了jieba分词模块,可以用pip install jieba安装。

https://github.com/zcsxll/bayesian_spam

参考链接

https://blog.csdn.net/shijing_0214/article/details/51200965

你可能感兴趣的:(深度学习,朴素贝叶斯算法)