先前曾经看了一篇文章,一个老外程序员写了一些很牛的Shell脚本,包括晚下班自动给老婆发短信啊,自动冲Coffee啊,自动扫描一个DBA发来的邮件啊, 等等。于是我也想用自己所学来做一点有趣的事情。我的想法如下:
在这个系列的文章中,你会学到:
这个系列的文章还会涉及到scrapy,pandas,numpy的一些知识,遇到这些知识的时候我会具体解释的。这个系列的文章我会主要详细的介绍上面的第3步实现过程,其余的我会将源码放在github上供大家参考。下面,就让我们享受这个奇妙之旅吧。
众所周知,朴素贝叶斯是一种简单但是非常强大的线性分类器。它在垃圾邮件分类,疾病诊断中都取得了很大的成功。它只所以称为朴素,是因为它假设特征之间是相互独立的,但是在现实生活中,这种假设基本上是不成立的。那么即使是在假设不成立的条件下,它依然表现的很好,尤其是在小规模样本的情况下。但是,如果每个特征之间有很强的关联性和非线性的分类问题会导致朴素贝叶斯模型有很差的分类效果。
为了更好地了解朴素贝叶斯分类器是怎么工作的,了解贝叶斯法则是很必要的。它可以被简单地描述成下面的公式:
我们可以用一个关于老天是否下雨的例子来解释上面的公式。
我们可以看到,如果我们想要在给定现象下,预测某种结果的概率,我们必须知道:1、在给定这种结果下,出现这种现象的概率。2、出现这种结果的概率。3、出现这种现象的概率。
在实际应用中,我们的现象不可能只有一个,比如,在垃圾邮件分类中,甚至可能有几千个词的特征向量。下面,我将引入一些数学上的记号来统一后面的表达:
朴素贝叶斯的目标就是分别求得 P(ωj|给定现象)j∈{1,2,3,…,m} ,选出最大的概率。
下面我将分别解释上面的三个概率。
随机变量的独立性意味着我告诉你一个变量的出现,并不影响你相信另一个出现的可能。最简单的一个例子就是抛硬币,也就是第一次的反正面并不会影响你再一次抛出现反正面的概率(也就是0.5)。
朴素贝叶斯模型中,特征之间不仅仅是独立的,而且是加条件的独立的。比如说:我的特征向量 x中,有n个特征 ,那么我可以把概率写成下面的形式:
P(x|ωj) 的概率我们可以理解成:在给定属于某个类别的条件下,观察到出现现象 x 的概率。在特征向量中的每个特点的概率我们都可以通过极大似然估计(maximum-likelihood estimate)来求得,也就是简单地求某个特征在某个类别中的频率,公式如下:
现在,我要用一个简单的分类垃圾邮件的例子来阐明上面的概念。比如我有4封邮件,其中2封为垃圾邮件,特征向量中有4个特征。具体如下表:
样本序号 | love | buy | deal | cat | 是否为垃圾邮件 |
---|---|---|---|---|---|
1 | 1 | 0 | 0 | 1 | 不是 |
2 | 0 | 1 | 1 | 0 | 是 |
3 | 0 | 1 | 0 | 1 | 是 |
4 | 1 | 0 | 1 | 1 | 不是 |
现在我要求 P(buy,deal|spam) 这个概率,通过条件的独立性和极大似然估计,我们可以求出这个概率:
先验概率道理其实很简单,在上面的那个垃圾邮件的例子中,我们可以用极大似然估计来求得: 24 ,通式如下:
通过上面后验概率的公式,我们可知:如果先验概率服从均匀分布,那么后验概率将完全取决于条件概率和现象概率,然而现象概率是常量,所以后验概率就完全取决于条件概率了。
注意:我认为在某些分类应用中,先验概率应该去咨询应用领域的专家,你不能单凭样本中出现的概率来求得先验概率。比如:如果我的训练集中,下雨天的样本要比晴天的样本多,你不能说现实生活中下雨天的概率要比晴天的时候大。因此,对于某些应用,先验概率应该去咨询应用领域的专家。
现象概率是独立于类别的。比如上面那个垃圾邮件的例子,我想知道 P(deal) 这个现象发生的概率,我只需要找出我所有的样本中出现deal这个特征的概率,与属于哪个类别没有任何关系。
其实我们完全没有必要算出这个概率,因为我们要求属于哪个类别的概率最大,而在这个过程中,它对于每次计算类别的概率中(也就是 P(ωj|xi) )都是常量,所以它不会影响到最终的决策。
还是上面那个邮件的例子,假设我们要求 P(love|spam) ,我们会发现,在垃圾邮件中并没有出现love这个词,因此概率为0,如果这个条件概率为0,那么整个后验概率就为0。为了避免0概率的发生,我们可以加上平滑项。把上面条件概率的公式改为下面的形式:
现在,我们已经拥有了朴素贝叶斯的数学背景知识和其算法的过程。在下篇文章中,我将主要介绍朴素贝叶斯在文本分类中的模型和技巧,为我们的成人笑话分类打下良好的基础。