机器学习专题(二)—— 朴素贝叶斯算法的python实现

来源:互联网 发布:卖家淘宝客怎么玩 编辑:程序博客网 时间:2024/05/17 05:16

大家好,沉寂了好久之后,终于决定发第二篇文章。闲话少叙,请看正文。
朴素贝叶斯是贝叶斯决策论的一部分,在讲述贝叶斯之前,先阐述一下贝叶斯决策论。
一、贝叶斯决策论
贝叶斯决策论是概率框架下实施决策的基本方法。我们以多分类任务为例来解释其基本原理
1.1贝叶斯条件风险的提出:假设有N种可能的类别标记,即这里写图片描述,这里写图片描述表示将一个真实标记为这里写图片描述的样本误分为这里写图片描述所产生的损失。那么基于后验概率P(这里写图片描述|这里写图片描述),我们可以将样本x分类为这里写图片描述所产生的期望损失表示为:

这里写图片描述

上式也成为样本x上的“条件风险”。


那么贝叶斯分类的目标就是:找到一个判定准则h(.),使得R(h)的总体风险最小,也就是期望损失最小。显然,对于每个样本想,如果h能够最小化条件风险R(h(x)|x),则总体风险R(h)也将被最小化。这样我们就得到了贝叶斯判定准则,即:

为最小化总体风险,只需在每个样本x上选择能使条件风险R(c|x)最小的类别标记即可:
h

引用块内容称为“贝叶斯最优分类器”。


那么如果我们假定这里写图片描述
则由于

引用块内容

故问题可转化为求解P(c|x)的最大值,即

这里写图片描述

即对每个样本x,选择能使P(c|x)最大的类别标记之。

1.2 贝叶斯后验概率的计算:

接着上面的内容,我们知道,朴素贝叶斯决策的关键变为计算后验概率P(c|x)的值。估算P(c|x)通常有两种方法:
1)判别式模型:即通过直接建模P(C|X)来预测C;
2)生成式模型:即通过计算P(x,c)的联合分布,推出P(c|x)的值

决策树、BP神经网络、支持向量机等都属于“判别式模型”。这里我们采用“生成式模型”.
基于“贝叶斯定理”,我们知道:

P(c|x) = P(x,c)/P(x) = P(c)P(x|c) / P(x)

其中P(x)是用于归一化的“证据因子”,与类别标记无关。因此计算P(C|X)的问题转化为计算 P(C)P(X|C)。P(C)的计算通过频率估计即可获得,因此最终问题确定在了计算 P(X|C)上。
由此我们提出了“朴素贝叶斯分类器”


二、朴素贝叶斯分类器

由上面的讨论我们知道,计算类后验概率P(C|X)的难度主要在于计算类条件概率P(X|C).P(X|C)为样本所有属性的联合概率,如果假设样本的“所有属性是相互独立的“,则有:

引用块内容

其中这里写图片描述为x在第i个属性上的取值,d为属性的个数。由于P(X)不影响类标记,所以我们得出了“朴素贝叶斯分类”的判定准则为:

这里写图片描述

(敲黑板。。。这才是本文的重点)
需要注意的是:朴素贝叶斯分类是建立在“假设样本属性相互独立”的条件之上,其中

引用块内容

这里写图片描述为数据集D中第c类样本的集合,这里写图片描述这里写图片描述中第i个属性为这里写图片描述的样本的集合。
当然,如果样本的属性值为连续值,则这里写图片描述的计算可通过概率函数来获得。假定这里写图片描述,即属性值服从高斯分布,则有:

引用块内容

其中这里写图片描述这里写图片描述为第c类样本在第i个属性值上的“均值”和“方差”。

附加内容:
分析朴素贝叶斯分类的判定准则 这里写图片描述,我们发现:如果某个属性的类条件概率这里写图片描述的值为0,那么真个公式的值将会变为0,这显然是不符合实际情况的。为了避免这种“尴尬”,我们引出了“平滑”的概念(又称拉普拉斯修正)。
具体地,拉普拉斯修正是指:令N表示训练集中可能包含的样本类别总数,这里写图片描述表示第i个属性可能的取值数,则我们可以将P(c)和P(x|c)的计算修正为:
这里写图片描述
这样我们就会避免0乘以任何数得0的问题。
至此,朴素贝叶斯分类器的基本原理我们已经基本掌握在手。接下来我将要展示的是一个“朴素贝叶斯分类器”的python实现样例。


三、朴素贝叶斯分类的Python实现
本文Python代码来源于《机器学习实战》一书,源代码我添加了大量的注释,方便大家理解。我们先从介绍问题开始讲起。
本文的python实现是一个使用朴素贝叶斯对文档进行分类的简单示例。

3.1、加载数据集
那么首先我们需要的是一些文本数据,因此第一步为加载数据集:

"""使用Bayes分类器对文本进行分类"""from numpy import *# 从文本中构建词向量,词表到向量的转换函数def loadDataSet():    """    创建一些实验样本    :return:    """    # 进行词条切分后的文档集合,每一行向量代表一个文档    postingList =[['my','dog','has','flea','problems ','help','please'],                  ['maybe','not','take','him','to','dog','park','stupid'],                  ['my','dalmation','is','so','cute','I','love','him'],                  ['stop','posting','stupid','worthless','garbage'],                  ['mr','licks','ate','my','steak','how','to','stop','him'],                  ['quit','buying','worthless','dog','food','stupid']]    # 类别标签集合,表示文档是否为侮辱性文档    classVec = [0,1,0,1,0,1]    # 1代表侮辱性文字  0代表正常言论    return postingList,classVec

注:这里loadDataSet()函数创建了一些实验样本,该函数返回的第一个变量是已经进行了词条切分的文档集合postingList,这里文档数组一共有6行,表示有6个文档。第二个返回变量classVec则是6个文档的分类类型,1表示该文档含有侮辱性文字,0表示该文档为正常言论。

3.2、获取文档的词向量
在加载完文档数据集后,我们应该怎么使用这些文档呢?首先我们想到的是应该将这些文档转换为我们可以计算利用的变量。为此我们需要将一篇文档用“词向量”来表示,如何表示呢?
有一种方式就是先创建一个包含所有文档词汇的词列表集合,该集合中每个元素只出现一次。假设我们有一个含有10个单词的词列表集合,表示为 Dictionary = {x_1,x_2,……x_10},那么对于某篇文档y(该文档中包含的单词数量一定少于或者等于10),我们可以将其表示为一个长度为10的文本向量。向量的元素y[i]取值为:

y[i] = 0 ,如果Dictionary中第i个位置的单词没有出现在该文档
y[i] = 1 ,如果Dictionary中第i个位置的单词在该文档y中出现

所以通过这种方式,我们就可以将一篇文档用长度与词列表大小相同的向量来表示。下面createVocabList()函数就是创建一个不包含重复词汇的词列表。

def createVocabList(dataSet):    """建一个包含所有文档中出现的不重复词的列表    创    :param dataSet:    :return:    """    vocabSet = set([])      # 创建一个空集 set()函数返回一个无序不重复元素的集合    for document in dataSet:        vocabSet = vocabSet | set(document)     # 创建两个集合的并集    return list(vocabSet)

在创建为词汇列表之后,紧接着就是文档的向量化表示了,具体方式上面已经提到,这里直接贴代码

def setOfWords2Vec(vocabList,inputSet):    """    使用“词集模型”    :param vocabList: 词汇表    :param inputSet:  单个的文档    :return:  returnVec 词汇向量    """    returnVec = [0]*len(vocabList)  # 创建一个和词汇表等长的0向量,用来表示词汇表中的单词在文档中是否出现    # 对于文档中单词,如果在词汇表中存在,则将词汇向量的对应位置设为1,否则设为0    for word in inputSet:        if word in vocabList:            returnVec[vocabList.index(word)] =1     # index() 函数用于从列表中找出某个值第一个匹配项的索引位置。        else:            print("the word:%s is not in my Vocabulary!" % word)    return returnVec

注:setOfWords2Vec()函数的作用就是将某个文档y向量化。

3.3 训练算法:朴素贝叶斯算法的类条件概率的计算

在处理完所有的文档数据之后,接下来就需要计算贝叶斯算法用到的各种概率了。我们以完成数据处理的文档作为数据集。在已经知道一个词是否出现在一篇文档中,以及该文档所属的类别之后。我们就可以计算概率了。根据“朴素贝叶斯判定准则”:
1)计算P(C):
显然,P(C)的计算非常容易,我们只需要用类别i中的文档数除以总的文档数就可以了。这里一共有两种分类(侮辱性文档和非侮辱性文档)。
2)计算P(X|C):

================
未更完

阅读全文
0 0