python机器学习案例系列教程——文档分类器,朴素贝叶斯分类器,费舍尔分类器 - Go语言中文社区

python机器学习案例系列教程——文档分类器,朴素贝叶斯分类器,费舍尔分类器


全栈工程师开发手册 (作者:栾鹏)

python数据挖掘系列教程

github地址:https://github.com/626626cdllp/data-mining/tree/master/Bayes

贝叶斯分类过程概述:首先有一批已知分类的数据集。对每个输入对象提取特征,根据输入对象的特征属性和输入对象的所属分类,计算分类与特征属性之间的概率关系,以此来实现样本的训练。当对新的输入对象进行预测所属分类时,提取新输入对象的特征,根据训练好的概率,判断输入对象属于每个分类的概率。

先验概率和后验概率

教科书上的解释总是太绕了。其实举个例子大家就明白这两个东西了。

假设我们出门堵车的可能因素有两个(就是假设而已,别当真):车辆太多和交通事故。

堵车的概率就是先验概率 。

那么如果我们出门之前我们听到新闻说今天路上出了个交通事故,那么我们想算一下堵车的概率,这个就叫做条件概率 。也就是P(堵车|交通事故)。这是有因求果。

如果我们已经出了门,然后遇到了堵车,那么我们想算一下堵车时由交通事故引起的概率有多大,

那这个就叫做后验概率 (也是条件概率,但是通常习惯这么说) 。也就是P(交通事故|堵车)。这是有果求因。

下面的定义摘自百度百科:

先验概率是指根据以往经验和分析得到的概率,如全概率公式,它往往作为”由因求果”问题中的”因”出现.

后验概率是指依据得到”结果”信息所计算出的最有可能是那种事件发生,如贝叶斯公式中的,是”执果寻因”问题中的”因”.

朴素贝叶斯理论

朴素贝叶斯是贝叶斯决策理论的一部分,所以在讲述朴素贝叶斯之前有必要快速了解一下贝叶斯决策理论。

朴素贝叶斯对条件个概率分布做了条件独立性的假设。 比如下面的公式,假设有n个特征:

由于每个特征都是独立的,我们可以进一步拆分公式

所以说朴素贝叶斯分类器基于一个简单的假定:给定目标值时属性之间相互条件独立。

朴素贝叶斯推断的一些优点:

生成式模型,通过计算概率来进行分类,可以用来处理多分类问题。
对小规模的数据表现很好,适合多分类任务,适合增量式训练,算法也比较简单。

朴素贝叶斯推断的一些缺点:

对输入数据的表达形式很敏感。
由于朴素贝叶斯的“朴素”特点,所以会带来一些准确率上的损失。
需要计算先验概率,分类决策存在错误率。

费舍尔分类器

费舍尔方法,是前面介绍的朴素贝叶斯方法的一种替代方案,它可以给出非常精确的结果,尤其适合垃圾信息过滤。
与朴素贝叶斯过滤器利用特征概率来计算整篇文档的概率不同,费舍尔方法为文档中的每个特征都求得了分类的概率,然后又将这些概率组合起来,并判断其是否有可能构成一个随机集合。该方法还会返回每个分类的概率,这些概率彼此间可以进行比较。尽管这种方法更为复杂,但是因为它在为分类选择临界值(cutoff)时允许更大的灵活性,所以还是值得一学的。

文档分类过程

爬虫采集数据:提供文本文件。
提取特征数据:将文本文件解析成词条向量。
计算特征概率:为每个特征属性计算属于分类的概率
计算对象概率:根据特征概率计算对象概率
构建分类器:使用对象概率完成分类
分类器效果测试:构建一个完整的程序对一组文档进行分类,将错分的文档输出到屏幕上。

案例

本文以垃圾邮件识别为例进行python代码演示。

首先我们先定义一批简单的已知样本数据,也就是邮件内容和所属分类。当然后面我们会添加特征提取的地方,包含邮件时间,邮件来源,邮件标题,邮件质量等。分类也不仅限于垃圾和非垃圾,可以包含订阅邮件,推广邮件,有毒邮件,购物邮件,学习邮件等等。现在这里我们仅对邮件文本内容进行识别,将邮件区分为垃圾和非垃圾。

在分类器中,你需要重点理清,文章属于某个分类器的概率Pr(category|Document)和在指定分类中文章出现的概率Pr(Document|category)的区别

分类器对输入对象进行分类的原理就是判断输入对象(邮件文档)属于哪个分类的概率更大。
也就是比较在文档已知的情况下,属于每个分类的概率的大小。即Pr( category|Document))概率的大小。

样本数据集

# 邮件数据集,邮件内容和所属分类。这只是一个非常简单的数据集。学会了算法以后再使用复杂数据集。
data=[
    ['Nobody owns the water.','good'],
    ['the quick rabbit jumps fences','good'],
    ['buy pharmaceuticals now','bad'],
    ['make quick money at the online casino','bad'],
    ['the quick brown fox jumps','good'],
]

特征提取函数

要实现对输入对象进行分类,首要要能够对输入对象提取用于分类的特征。在邮件中特征就是单词,我们就是根据单词来进行垃圾邮件识别。
对输入对象进行特征提取。(对邮件文档提取对单词)

中文文档提取参考http://blog.csdn.net/luanpeng825485697/article/details/78857654

# 从输入对象中提取特征(文档中提取不重复单词)
def getwords(doc):
    splitter=re.compile('\W*')
    print(doc)
    # 根据非字母字符进行单词拆分
    words=[s.lower() for s in splitter.split(doc) if len(s)>2 and len(s)<20]

    # 只返回一组不重复的单词。(特征不重复)
    return dict([(w,1) for w in words])

先验概率(任一样本属于指定分类的概率)

先验概率

条件概率(指定分类中指定特征出现的概率)

在朴素贝叶斯中,设样本第