最新公告
  • 欢迎光临数据科学与编程,我们是数据学科学兴趣交流小组立即加入我们
  • python机器学习:朴素贝叶斯分类算法

    贝叶斯分类是一类分类算法的总称,这类算法均以贝叶斯定理为基础,故统称为贝叶斯分类。而朴素朴素贝叶斯分类是贝叶斯分类中最简单,也是常见的一种分类方法。这篇文章我尽可能用直白的话语总结一下。

    1  分类问题综述

     对于分类问题,其实谁都不会陌生,日常生活中我们每天都进行着分类过程。例如,当你看到一个人,你的脑子下意识判断他是学生还是社会上的人;你可能经常会走在路上对身旁的朋友说“这个人一看就很有钱”之类的话,其实这就是一种分类操作。

    既然是贝叶斯分类算法,那么分类的数学描述又是什么呢?

    从数学角度来说,分类问题可做如下定义:已知集合,确定映射规则y = f(x),使得任意有且仅有一个,使得成立

    其中C叫做类别集合,其中每一个元素是一个类别,而I叫做项集合(特征集合),其中每一个元素是一个待分类项,f叫做分类器。分类算法的任务就是构造分类器f。

    分类算法的内容是要求给定特征,让我们得出类别,这也是所有分类问题的关键。那么如何由指定特征,得到我们最终的类别,也是我们下面要讲的,每一个不同的分类算法,对应着不同的核心思想。

    本篇文章,我会用一个具体实例,对朴素贝叶斯算法几乎所有的重要知识点进行讲解。

    2  朴素贝叶斯分类

    那么既然是朴素贝叶斯分类算法,它的核心算法又是什么呢?

    是下面这个贝叶斯公式:

    换个表达形式就会明朗很多,如下:

    我们最终求的p(类别|特征)即可!就相当于完成了我们的任务。

    3  例题分析

    下面我先给出例子问题。

    给定数据如下:

    现在给我们的问题是,如果一对男女朋友,男生想女生求婚,男生的四个特点分别是不帅,性格不好,身高矮,不上进,请你判断一下女生是还是不嫁

    这是一个典型的分类问题,转为数学问题就是比较p(嫁|(不帅、性格不好、身高矮、不上进))与p(不嫁|(不帅、性格不好、身高矮、不上进))的概率谁的概率大,我就能给出嫁或者不嫁的答案!

    这里我们联系到朴素贝叶斯公式:

    我们需要求p(嫁|(不帅、性格不好、身高矮、不上进),这是我们不知道的,但是通过朴素贝叶斯公式可以转化为好求的三个量.

    p(不帅、性格不好、身高矮、不上进|嫁)、p(不帅、性格不好、身高矮、不上进)、p(嫁)(至于为什么能求,后面会讲,那么就太好了,将待求的量转化为其它可求的值,这就相当于解决了我们的问题!

    4  朴素贝叶斯算法的朴素一词解释

    那么这三个量是如何求得?

    是根据已知训练数据统计得来,下面详细给出该例子的求解过程。

    回忆一下我们要求的公式如下:

    那么我只要求得p(不帅、性格不好、身高矮、不上进|嫁)、p(不帅、性格不好、身高矮、不上进)、p(嫁)即可,好的,下面我分别求出这几个概率,最后一比,就得到最终结果。

    p(不帅、性格不好、身高矮、不上进|嫁) = p(不帅|嫁)*p(性格不好|嫁)*p(身高矮|嫁)*p(不上进|嫁),那么我就要分别统计后面几个概率,也就得到了左边的概率!

    等等,为什么这个成立呢?学过概率论的同学可能有感觉了,这个等式成立的条件需要特征之间相互独立吧!

    对的!这也就是为什么朴素贝叶斯分类有朴素一词的来源,朴素贝叶斯算法是假设各个特征之间相互独立,那么这个等式就成立了!

    但是为什么需要假设特征之间相互独立呢?

    1、我们这么想,假如没有这个假设,那么我们对右边这些概率的估计其实是不可做的,这么说,我们这个例子有4个特征,其中帅包括{帅,不帅},性格包括{不好,好,爆好},身高包括{高,矮,中},上进包括{不上进,上进},那么四个特征的联合概率分布总共是4维空间,总个数为2*3*3*2=36个。

    36个,计算机扫描统计还可以,但是现实生活中,往往有非常多的特征,每一个特征的取值也是非常之多,那么通过统计来估计后面概率的值,变得几乎不可做,这也是为什么需要假设特征之间独立的原因。

    2、假如我们没有假设特征之间相互独立,那么我们统计的时候,就需要在整个特征空间中去找,比如统计p(不帅、性格不好、身高矮、不上进|嫁),

    我们就需要在嫁的条件下,去找四种特征全满足分别是不帅,性格不好,身高矮,不上进的人的个数,这样的话,由于数据的稀疏性,很容易统计到0的情况。 这样是不合适的。

    根据上面俩个原因,朴素贝叶斯法对条件概率分布做了条件独立性的假设,由于这是一个较强的假设,朴素贝叶斯也由此得名!这一假设使得朴素贝叶斯法变得简单,但有时会牺牲一定的分类准确率。

    好的,上面我解释了为什么可以拆成分开连乘形式。那么下面我们就开始求解!

    我们将上面公式整理一下如下:

    下面我将一个一个的进行统计计算(在数据量很大的时候,根据中心极限定理,频率是等于概率的,这里只是一个例子,所以我就进行统计即可)。

    p(嫁)=?

    首先我们整理训练数据中,嫁的样本数如下:

    则 p(嫁) = 6/12(总样本数) = 1/2

    p(不帅|嫁)=?统计满足样本数如下:

    则p(不帅|嫁) = 3/6 = 1/2 在嫁的条件下,看不帅有多少

    p(性格不好|嫁)= ?统计满足样本数如下:

    则p(性格不好|嫁)= 1/6

    p(矮|嫁) = ?统计满足样本数如下:

    则p(矮|嫁) = 1/6

    p(不上进|嫁) = ?统计满足样本数如下:

    则p(不上进|嫁) = 1/6

    下面开始求分母,p(不帅),p(性格不好),p(矮),p(不上进)

    统计样本如下:

    不帅统计如上红色所示,占4个,那么p(不帅) = 4/12 = 1/3

    性格不好统计如上红色所示,占4个,那么p(性格不好) = 4/12 = 1/3

    身高矮统计如上红色所示,占7个,那么p(身高矮) = 7/12

    不上进统计如上红色所示,占4个,那么p(不上进) = 4/12 = 1/3

    到这里,要求p(不帅、性格不好、身高矮、不上进|嫁)的所需项全部求出来了,下面我带入进去即可,

    = (1/2*1/6*1/6*1/6*1/2)/(1/3*1/3*7/12*1/3)

    下面我们根据同样的方法来求p(不嫁|不帅,性格不好,身高矮,不上进),完全一样的做法,为了方便理解,我这里也走一遍帮助理解。首先公式如下:

    下面我也一个一个来进行统计计算,这里与上面公式中,分母是一样的,于是我们分母不需要重新统计计算!

    p(不嫁)=?根据统计计算如下(红色为满足条件):

    则p(不嫁)=6/12 = 1/2

    p(不帅|不嫁) = ?统计满足条件的样本如下(红色为满足条件):

    则p(不帅|不嫁) = 1/6

    p(性格不好|不嫁) = ?据统计计算如下(红色为满足条件):

    则p(性格不好|不嫁) =3/6 = 1/2

    p(矮|不嫁) = ?据统计计算如下(红色为满足条件):

    则p(矮|不嫁) = 6/6 = 1

    p(不上进|不嫁) = ?据统计计算如下(红色为满足条件):

    则p(不上进|不嫁) = 3/6 = 1/2

    那么根据公式:

    p (不嫁|不帅、性格不好、身高矮、不上进) = ((1/6*1/2*1*1/2)*1/2)/(1/3*1/3*7/12*1/3)

    很显然(1/6*1/2*1*1/2) > (1/2*1/6*1/6*1/6*1/2)

    于是有p (不嫁|不帅、性格不好、身高矮、不上进)>p (嫁|不帅、性格不好、身高矮、不上进)

    所以我们根据朴素贝叶斯算法可以给这个女生答案,是不嫁!!!!

    5  朴素贝叶斯分类的优缺点

    优点:

    (1) 算法逻辑简单,易于实现(算法思路很简单,只要使用贝叶斯公式转化医学即可!

    (2)分类过程中时空开销小(假设特征相互独立,只会涉及到二维存储

    缺点:

    理论上,朴素贝叶斯模型与其他分类方法相比具有最小的误差率。但是实际上并非总是如此,这是因为朴素贝叶斯模型假设属性之间相互独立,这个假设在实际应用中往往是不成立的,在属性个数比较多或者属性之间相关性较大时,分类效果不好。

    而在属性相关性较小时,朴素贝叶斯性能最为良好。对于这一点,有半朴素贝叶斯之类的算法通过考虑部分关联性适度改进。

    朴素贝叶斯算法+中文情感分类

    本人对贝叶斯分类的理解,简单的概括就是:要想由什么特征属性来判定属于哪种分类,即求,可以由在这种分类中具有这些特征属性的概率求得,而可以通过训练集得到。算法针对中文文本分析,情感分类区别在于特征属性的选择,前者是将所有文本内容的分词去除重复后,得到词典,后者是将情感词作为特征属性,情感词由各大学教授,权威人士在各自研究领域内公布了各自的情感分词库,免费公开(真诚感谢)。中文文本分析的编程实现已在上面提到的书本内完成,因它采取的是Scikit-Learn模块的朴素贝叶斯分类模块,可以进Scikit-Learn官方网站下载朴素贝叶斯分类模块源码学习,也可以自己编写贝叶斯算法类,本人觉得自己编写贝叶斯算法类有利于对算法的理解,在理解后,再采取Scikit-Learn模块进行相应的项目开发。故本人将书本中编写的贝叶斯算法类运用在中文情感分类中,增加对算法的理解。

    项目实践

    本人实现的中文情感分类过程,分为两个部分:(1)训练集数据的准备过程,(2)文本情感分类;

    训练集数据的准备过程分为:

    (1)文本下载:文本下载的方式有很多,其中高效的方法就是从文本网站上下载各个文章,下载可采取网络爬虫方法,本人采取的是python+scrapy框架的方法对文本网页进行文章自动爬取(链接:https://pan.baidu.com/s/1EJ2QLjw_bEUza5JG9jDSLQ 密码:czuo),共下载文本(497)然后对文本进行分类,语料包括:积极文本(150),消极文本(266),其他的因情感倾向不明显,就不加入训练集。

    (2)中文分词,本人将(1)中的文本采取jieba模块进行中文分词(代码在后面贴上)

    (3)下载情感词典,链接: http://pan.baidu.com/s/1u12m0 ,来自台湾大学教授免费公布

    将爬虫到的xml文本进行解析以及中文分词,得到语料结构为list[[文本1],[文本2],[文本3]…[文本n]],代码如下:

    #xml文件解析

    #中文文本解析

    训练集准备就绪,以下进行文本分类

    结合代码,文本情感分类这一部分是算法核心,具体解析过程如下:

    重点:文本情感分类有两种加权方法,一种是词频加权,一种是TF-IDF策略,这里重点分析下tf-idf策略以及怎么通过训练集求出

    即代码中 def calc_tfidf(self,trainset),def cate_prob(self,classVec)函数的解析

    首先了解下如下几个数据结构:

    a、idf矩阵:

     n为情感词典词的总数,元素表示情感词编号m在所有文本中出现的次数,注意:如果在一文本中情感词 m 出现了多次,也只算一次。接着将上面的idf数组转化为逆向文件频率。

    self.idf = np.log(float(self.doclength)/(self.idf+1))

    #防止该词语不在语料中,就会导致分母为零。  


     

     

    b、tf矩阵:

    其中,n表示情感词典词的总数,m表示所有文本个数,即创建了一个二维矩阵,矩阵元素表示在文本标号m中,出现标号为n的情感词的词频,接着再将tf消除不同句长导致的偏差

    self.tf[indx] = self.tf[indx]/float(len(trainset[indx]))  

    即将矩阵元素除以标号为m文本的所有单词数

    这样tf,idf数组向量求出后再相乘,就得到了TF-IDF权重,将权重再赋予tf矩阵


    不得不说,这个策略对文本分类的重要性。

    c、tdm矩

    既然权重得到了,接下来就是求,即


    这个概率,本人在捉摸多次后理解如下:

    首先,建立tdm矩阵,矩阵行为分类数,在本项目中,行数就为2,列为情感词典个数,为11086,而将tf中属于同一类的行相加,即得到tdm矩阵。

    其次,建立sunlist矩阵,行数为分类数,列数为1,其元素是一标量,将tdm的属于同一类的行数元素累加,比如具体点的就是将tdm中是积极类的行数累加,

    那么tdm=tdm/sumlista就是,即tdm最终保存的是在一分类中具有这些特征属性的概率。

    得到tdm矩阵后,就可以对测试文本进行分类了,首先,必须要将测试文本进行分词,本代码是输入的是直接分词好的。然后将测试集映射到当前词典,得到测试向量testset即情感词典,就是求在测试文本中,各个情感词出现的频数,然后将testset与tdm矩阵相乘,将结果最大的值对应的分类作为这个测试文本的分类。https://blog.csdn.net/qq_34533544/article/details/77430056?yyue=a21bo.50862.201879

    本站上原创文章未经作者许可,不得用于商业用途,仅做学习交流使用,本站免责声明。转载请注明出处,否则保留追究法律责任的权利。《署名-非商业性使用-相同方式共享 4.0 国际 (CC BY-NC-SA 4.0)》许可协议授权
    数据科学与编程 » python机器学习:朴素贝叶斯分类算法

    发表评论

    • 52会员总数(位)
    • 320资源总数(个)
    • 25本周发布(个)
    • 3 今日发布(个)
    • 333稳定运行(天)

    提供最优质的博文资源集合

    立即阅览 了解详情