朴素贝叶斯案例1:进行文档/评论分类(python实现)

时间:2022-06-16 05:41:36

    机器学习的一个重要应用就是文档的自动分类,比如一封电子邮件、新闻报道、用户留言、*公文等。在文档分类中,比如一封电子邮件就是一个实例,而电子邮件中的某些元素(词语)则构成特征。我们可以观测文档中出现的词,并把每个词的出现或者不出现作为一个特征,这样得到的特征数目就会跟词汇表中的词目一样多。

    朴素贝叶斯是比较常用的算法,朴素的含义是假设特征之间相互独立,为啥需要这个假设呢?

    假设词汇表中有1000个单词,要得到好的概率分布,就需要足够的数据样本,假设每个特征需要N个样本,那么对于1000特征的词汇,则需要N的1000次幂。随着特征数目增大样本数会迅速增长。但如果假设特征之间相互独立,则样本数可以由N的1000次幂减少到1000*N个。

    所谓的独立指的是统计意义上的独立,即一个特征或者单次出现的可能性与它和其他单词相邻没有关系。比如,单词bacon出现在unhealthy和出现在delicious后面的概率相等,当然这个假设并不正确,两者肯定不相等,这个假设正是朴素贝叶斯中的朴素的概念。朴素贝叶斯的另外一个假设是每个特征同等重要。其实这个假设也有问题,如果要判断留言板的留言是否恰当,可能并不需要看完所有的1000个单词,而只需要看10-20个单词(特征)即可做出判断。

    尽管朴素贝叶斯有这些小瑕疵,但是实际的效果仍然很好。

案例:

    以斑点狗论坛留言板为例,需要构建一个快速过滤器,屏蔽一些侮辱性的言论。对此类问题需要建立两个类别,侮辱和非侮辱类,使用1和0分别表示。

1、将文本转化为数字向量

    要从文本中获取特征,需要先拆分文本。将文本片段表示为一个词条向量,其中值1表示词条出现在文档中,0表示词条未出现。

1)导入数据

朴素贝叶斯案例1:进行文档/评论分类(python实现)

2)创建一个包含在所有文档中不重复的词汇表

朴素贝叶斯案例1:进行文档/评论分类(python实现)

运行案例如下:

朴素贝叶斯案例1:进行文档/评论分类(python实现)

3)获取词汇表之后,就可以根据词汇表以及样本文档,输出样本的数字向量。

向量的每一个元素为0或者1,分别表示词汇表中的单词是否在输入文档中出现。

朴素贝叶斯案例1:进行文档/评论分类(python实现)

案例结果:

朴素贝叶斯案例1:进行文档/评论分类(python实现)

将训练文本全部转为数字向量。

向量的每个元素0,或1 代表评论中的词是否在词汇表中出现,向量的长度为词汇表的长度。

朴素贝叶斯案例1:进行文档/评论分类(python实现)

2、训练算法,从词向量计算概率。

    贝叶斯公式:p(h+|D)=p(D|h+)*p(h+)/P(D), h+代表侮辱性留言,D表示评论。现在D里面含有N个单词d1、d2、d3...dn。如果将D展开为一个个特征,可以将P(D|h+)写成P(d1,d2,...dn | h+),这里假设各个特征d1...dn之间都相互独立,该假设也称为条件独立性,它意味着可以将P(d1,d2,...dn | h+)转化为P(d1 | h+)*P(d2 | h+)*...P(dn | h+),这就极大的简化了计算过程。

程序思路:

计算每个类别汇总的文档数目

对每篇训练文档:

  • 对每个类别:

        如果词条出现在文档中,则增加该词条的计数值

        增加所有词条的计数值

  • 对每个词条:

      将该词条的数目除以总词条数目得到条件概率

  • 返回每个类别的条件概率

朴素贝叶斯案例1:进行文档/评论分类(python实现)

执行案例:

朴素贝叶斯案例1:进行文档/评论分类(python实现)

3、根据朴素贝叶斯进行分类。

下面就是分别求出P(h+|D)、P(h-|D),然后根据两者的大小,取值大的类别做决策。

P(h+|D) = P(D|h+) *P(h+) / P(D) =  (P(d1 | h+)*P(d2 | h+)*...P(dn | h+))*P(h+) / P(D)

P(h-|D) = P(D|h-) *P(h-) / P(D) =  (P(d1 | h-)*P(d2 | h-)*...P(dn | h-))*P(h-) / P(D)

    在计算P(d1 | h+)*P(d2 | h+)*...P(dn | h+)时,假设有一个P(di | h+)=0,那么这个式子的乘积也会0,为降低这种影响,可将素有词的出现数均初始化为1,将分母初始化为2

另外一个问题是下溢出,这是由于太多很小的数相乘,四舍五入会得到0,此时的解决办法是对乘积取自然对数。主要参考是因为ln(a*b)=ln(a)+ln(b),因为为f(x)和ln(f(x))的曲线变化趋势一致。虽然取值不一样,但不影响我们的判断。

朴素贝叶斯案例1:进行文档/评论分类(python实现)

测试案例:

朴素贝叶斯案例1:进行文档/评论分类(python实现)