基于概率论的分类方法:朴素贝叶斯
来源:互联网 发布:python iteritems函数 编辑:程序博客网 时间:2024/05/01 11:47
在这里我们将完成两个过程:1.我们将充分利用Python的文本处理能力将文档切分为词向量,然后利用词向量对文档进行分类。2.我们将构建另一个分类器,观察其在真实的垃圾邮件数据集中的过滤效果。
1.概率知识:
1.1贝叶斯决策理论
朴素贝叶斯是贝叶斯决策理论的一部分,所以讲述朴素贝叶斯之前有必要快速了解一下贝叶斯决策理论。
假设我们有一个数据集,它由两类数据组成,数据分布如图1-1所示:
我们现在用p1(x,y)表示数据点(x,y)属于类别1(图中用圆点表示的类别)的概率,用p2(x,y)属于类别2(图中用三角形表示的类别)的概率,那么对于一个新数据点(x,y),可以用下面的规则来进行判断类别:
如果p1(x,y)>p2(x,y),那么类别为1。
如果p2(x,y)>p1(x,y),那么类别为2。
也就是说,我们会选择高概率对应的类别。这就是贝叶斯决策理论的核心思想,即选择具有最高概率的决策。
1.2 条件概率
假设现在有一个装了7块石头的盒子,其中3块是灰色的,4块是黑色的,所以从盒子中随机取出一块石头,是灰色的概率为3/7,是黑色的概率是4/7。我们使用p(grey)来表示取到灰色石头的概率。
如果这7块石头放在A、B两个盒子里(A中有2个灰色,2个黑色;B中有1个灰色,2个黑色),那么上述概率该怎么求?
有两种方法求条件概率:1、假定计算的是从B盒取到灰色石头的概率,记作p(gray|bucketB)。条件概率的计算公式如下所示:p(gray|bucketB)=p(gray and bucketB)/p(bucketB).首先,用B盒中灰色的个数除以两个盒子的总数,得到p(gray and bucketB)=1/7,其次,由于B盒中有3块石头,而总数为7,于是p(bucketB)=3/7.不难得到,p(gray|bucketB)的值为1/3,p(gray|bucketA)的值为2/4;
2、另一种计算条件概率的方法为贝叶斯准则,通过交换条件概率中的条件与结果,即如果已知p(x|c),要求p(c|x),那么可以通过以下计算方法得到:
1.3 使用条件概率来分类
具体应用贝叶斯准则得到:
使用这些定义,可以定义贝叶斯分类准则为:
如果
如果
2.使用Python进行文本分类
要从文本中获取特征,需要先拆分文本。如何做尼?这里的特征是来自文本的词条(token),一个词条是字符的任意组合。可以把词条想象为单词,也可以是非单词词条,如URL、IP地址或者任意其他字符串。然后将每一个文本片段表示为一个词条向量,其中值为1表示词条出现在文档中,0表示词条未出现。
接下来首先介绍将文本转换为数字向量的过程,然后介绍如何基于这些向量来计算条件概率,并在此基础上构建分类器。最后还要介绍一些利用Python实现朴素贝叶斯过程中需要考虑的问题。
2.1 准备数据:从文本中构建词向量
考虑出现在所有文档中的所有单词,再决定将哪些词纳入词汇表,然后必须要将每一篇文章转换为词汇表上的向量。
程序清单2-1:词表到向量的转换函数
def createVocabList(dataSet): vocabSet = set([]) for document in dataSet: vocabSet = vocab Set | set(document) return list(vocabSet)
creatVocabList()会创建一个包含在所有文档中出现的不重复词的列表。将词条列表输给set构造函数,set就会返回一个不重复的词表。首先,创建一个空集合,然后将每篇文档返回的新词集合添加到该集合中。操作符|用于求两个集合的并集。
def setOfWords2Vec(vocabList,inputSet) returnVec = [0]*len(vocabList) for word in inputSet: if word in vocabList: returnVec[vocabList.index(word)] = 1 else:print"the word: %s is not in my vocabulary!"%word return returnVec
获得词汇表后,便可以使用函数setOfWords2Vec(),该函数的输入参数为词汇表以及某个文档,输出的是文档向量,向量的每一元素为1或0,分别表示词汇表中的单词再输入文档中是否出现。函数首先创建一个和词汇表等长的向量,并将其元素设置为0,接着,遍历文档中的所有单词,如果出现了词汇表中的单词,则将输出的文档向量中的对应值设为1。
2.2 训练算法:从词向量计算概率
程序清单2-2: 朴素贝叶斯分类器训练函数
def trainNB0(trainMatrix , trainCategory) numTrainDocs = len(trainMatrix) numWords = len(trainMatrix[0]) pAbusive = sum(trainCategory)/float(numTrainDocs) p0Num = zeros(numWords); p1Num = zeros(numWords) p0Denom = 0.0; p1Denom = 0.0 for i in range(numTrainDocs): if trainCategory[i] == 1: p1Num += trainMatrix[i] #每个单词出现的频次 p1Denom += sum(trainMatrix[i])#所有出现的单词总数 else: p0Num += trainMatrix[i] p0Denom += sum(trainMatrix[i]) p1Vect = p1Num/p1Denom #每个单词出现的次数除以该类别中的总单词数 p0Vect = p0Num/p0Denom
输入参数为所有文档的词向量trainMatrix,以及由每篇文档类别标签所构成的向量trainCategory。
2.3 测试算法:根据现实情况修改分类器
利用贝叶斯分类器对文档进行分类时,要计算多个概率的乘积以获得文档属于某个类别的概率,即计算
p0Num = ones(numWords); p1Num = ones(numWords) p0Denom = 2.0; p1Denom = 2.0
另一个问题是下溢出。当计算乘积
p1Vect = log(p1Num/p1Denom) p0Vect = log(p0Num/p0Denom)
程序清单2-3:朴素贝叶斯分类函数
def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1): p1 = sum(vec2Classify*p1Vec)+log(pClass1) p0 = sum(vec2Classify*p0Vec)+log(1.0 - pClass1) if p1>p0: return 1 else: return 0
有4个输入:要分类的向量vec2Classify以及使用函数trainNB0()计算得到的三个概率。
2.4 示例:使用朴素贝叶斯过滤垃圾邮件
2.4.1 准备数据:切分文本
程序清单2-4:
def textParse(bigString): import re listOfTokens = re.split(r'\W*',bigString) return [tok.lower() for tok in listOfTokens if len(tok)>2]
返回长度大于2并转换成小写的字符串。
2.4.2 测试算法:使用朴素贝叶斯进行交叉验证
程序清单2-5:
def spamTest(): docList = []; classList = []; fullText = [] for i in range(1,26): wordList = textParse(open('email/spam/%d.txt' %i).read()) docList.append(wordList) fullText.extend(wordList) classList.append(1) wordList = textParse(open('email/ham/%d.txt' %i).read()) docList.append(wordList) fullText.extend(wordList) classList.append(0) vocabList = creatVocabList(docList) trainingSet = range(50);testSet = [] for i in range(10): randIndex = int(random.uniform(0,len(trainingSet))) testSet.append(trainingSet[randIndex]) del(trainingSet[randIndex]) trainMat = []; trainClasses = [] for docIndex in trainingSet: trainMat.append(setOfWords2Vec(vocabList,docList[docIndex])) trainClasses.append(classList[docIndex]) p0V,p1V,pSpam = trainNB0(array(trainMat),array(trainClasses)) errorCount = 0 for docIndex in testSet: wordVector = setOfWords2Vec(vocabList,docList[docIndex]) if classifyNB(array(wordVector),p0V,p1V,pSpam) !=classList[docIndex]: errorCount += 1 print 'classification error :',docList[docIndex] print 'the error rate is: ',float(errorCount)/len(testSet)
导入文件夹spam和ham下的文本文件,接下来构建一个测试集与一个训练集,本例中共有50封电子邮件,其中10封被随机选择为测试集。变量trainingSet是一个整数列表,其中的值从0到49。接下来,随机选择其中10个文件。选择出的数字所对应的文档被添加到测试集,同时也将其从训练集中剔除。这种随机选择数据的一部分作为测试集,而剩余部分作为训练集的过程称为留存交叉验证。
- 基于概率论的分类方法:朴素贝叶斯
- 基于概率论的分类方法:朴素贝叶斯
- 基于概率论的分类方法:朴素贝叶斯
- 基于概率论的分类方法:朴素贝叶斯
- 基于概率论的分类方法:朴素贝叶斯
- 基于概率论的分类方法:朴素贝叶斯
- 基于概率论的分类方法:朴素贝叶斯
- 基于概率论的分类方法:朴素贝叶斯
- 基于概率论的分类方法:朴素贝叶斯
- 基于概率论的分类方法--朴素贝叶斯
- C++实现基于概率论的分类方法--朴素贝叶斯分类
- 机器学习实战--基于概率论的分类方法:朴素贝叶斯
- 机器学习之基于概率论的分类方法 : 朴素贝叶斯
- 基于概率论的分类方法:朴素贝叶斯算法实践学习
- 《机器学习实战》笔记之四——基于概率论的分类方法:朴素贝叶斯
- 机器学习实战python版第四章基于概率论的分类方法 朴素贝叶斯
- 机器学习实战(3)--(基于概率论的分类方法)朴素贝叶斯
- 基于概率论的分类方法:朴素贝叶斯---过滤网站恶意留言
- 计算机视觉、机器学习相关领域论文和源代码大集合
- [ZJOI2008] [BZOJ1036] 树的统计Count
- poj EXTENDED LIGHTS OUT 1222 (高斯消元)
- UIViewContentMode的各种样式
- 部分IE8使用的兼容CSS3属性的方法
- 基于概率论的分类方法:朴素贝叶斯
- 对象已死?
- 遮罩层
- 嵌入式软件书籍
- git解决分支冲突
- 获取某一网页的内容
- 程序员必须知道的10大基础实用算法及其讲解
- JavaWEB 核心编程视频教程 03
- (1) Hive JOIN语句详解