之前的两种算法都需要分类器指出实例究竟属于什么类别。这次讲到的贝叶斯算法,是从概率的角度进行分类的。
1、条件概率:
p(A|B)=p(AB)/p(B)
也就是在B的条件下A出现的概率。
交换条件中的条件与结果:
p(B|A)=p(A|B)*p(B)/p(A)
2、朴素贝叶斯算法的两个假设:
(1)每个特征之间都是独立的,这就使得公式:
p((f1,f2,...fn)|c)=p(f1|c)p(f2|c)...p(fn|c)
(2)每个特征同等重要,我们拿文本分类做例子,把文档中的单词作为特征。这种假设使得我们在进行分类的过程中无需考虑单词出现的次数,只考虑单词出现与否。这也就贝叶斯算法的贝努利模型实现方式。
注:贝叶斯的另一种实现方式为多项式模型,在这种模型中则需要考虑单词的出现次数。我们在后面会进行介绍。
3、输入数据
依照机器学习的步骤,首先是准备输入数据。我们同样生成一个简单的训练数据。
新建文件bayes.py,编辑代码如下:
#产生训练数据 def loadDataSet(): #该数据取自某狗狗论坛的留言版 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']] #标注每条数据的分类,这里0表示正常言论,1表示侮辱性留言 classVec = [0,1,0,1,0,1] return postingList,classVec[/code]
4、接下来我们就要统计文档中的单词种类了,也就是数据集中的特征。编辑如下代码:
#建立词汇表 def createVocabList(dataSet): #首先建立一个空集 vocabSet=set([]) #遍历数据集中的每条数据 for document in dataSet: #这里就显示出了python的强大 #这条语句中首先统计了每条数据的词汇集,然后与总的词汇表求并集 vocabSet=vocabSet|set(document) return list(vocabSet)
有了词汇表,我们就可以通过词汇表对输入的数据进行分析了。我们构建一个函数分析输入数据。该函数的输入参数为:词汇表及数据词条。输出为何词汇条同样大小的向量,其中向量中的值非0即1,表示词条中是否出现该单词。
处理过程:建立和等长的向量,遍历文档中的所有单词,如果文档在那个出现了词汇表中的单词,则将输出的文档向量中的对应值设为1,具体代码如下:
#按照词汇表解析输入 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
接下来,看一下函数的执行效果:
5、接下来我们就要实现贝叶斯算法了,让我们再次回想刚才的条件概率公式:
p(B|A)=p(A|B)*p(B)/p(A)
对于我们的问题可以写为:
p(ci|w)=p(w|ci)*p(ci)/p(w)
这里的w表示一个向量,即将文本解析之后的向量。利用第二个假设,公式可以写为:
p(ci|w)=(p(w1|ci)p(w2|ci)...p(wn|ci))*p(ci)/p(w)
首先说一下,我们在程序中要做的一些近似。由于有的单词的数目为0,则P(Wi|Ci)=0,那么会造成p(ci|w)=(p(w1|ci)p(w2|ci)...p(wn|ci))*p(ci)/p(w)=0,这样就会影响概率结果,因此我们在初始化的过程,将所有单词的初始化数目设为1。
另一问题就是下溢出,每个概率可能都很小,那么相乘之后就更小,会造成四舍五入之后为0,解决这个问题的办法是我们对概率取对数。
下面我们就通过代码实现这个概率:
#朴素贝叶斯分类器训练函数 #输入参数trainMatrix表示输入的文档矩阵,trainCategory表示每篇文档类别标签所 构成的向量 def trainNB0(trainMatrix,trainCategory): #留言数目 numTrainDocs=len(trainMatrix) #变换矩阵的列数目,即词汇表数目 numWords=len(trainMatrix[0]) #侮辱性留言的概率 pAbusive=sum(trainCategory)/float(numTrainDocs) p0Num=ones(numWords) p1Num=ones(numWords) p0Denom=2.0 p1Denom=2.0 for i in range(numTrainDocs): #统计每类单词的数目,注意我们这里讨论的是一个二分问题 #所以可以直接用一个if...else...即可,如果分类较多,则需要更改代码 if trainCategory[i]==1: p1Num+=trainMatrix[i] p1Denom+=sum(trainMatrix[i]) else: p0Num+=trainMatrix[i] p0Denom+=sum(trainMatrix[i]) p1Vec=log(p1Num/p1Denom) p0Vec=log(p0Num/p0Denom) #函数返回两个概率向量,及一个概率 return p0Vec,p1Vec,pAbusive
测试函数:
有了之前的所有准备,我们写贝叶斯算法就非常简单了。
#朴素贝叶斯分类函数 def classifyNB(vec2Classify,p0Vec,p1Vec,pClass): p1=sum(vec2Classify*p1Vec)+log(pClass) p0=sum(vec2Classify*p0Vec)+log(1-pClass) if p1>p0: return 1; else: return 0;
我们在程序里再写一个内嵌的测试函数:
#内嵌测试函数 def testingNB(): listOPosts,listClasses=loadDataSet() myVocabList=createVocabList(listOPosts) trainMat=[] for postinDoc in listOPosts: trainMat.append(setOfWords2Vec(myVocabList,postinDoc)) p0V,p1V,p1=trainNB0(trainMat,listClasses) testEntry=['love','my','dalmation'] thisDoc=setOfWords2Vec(myVocabList,testEntry) print testEntry,"classified as:",classifyNB(thisDoc,p0V,p1V,p1) testEntry=['garbage','stupid'] thisDoc=setOfWords2Vec(myVocabList,testEntry) print testEntry,"classified as:",classifyNB(thisDoc,p0V,p1V,p1)
测试算法:
6、之前的算法我们只考虑了单词出现与否,使用的是一种词集模型。贝叶斯有两种实现方式,另一种多项式模型,需要考虑每个单词出现的次数,就是所谓的词袋模型。为了适应这种词袋模型,我们需要对函数setOfWords2Vec作一下修改:
#词袋模型的转换函数 def bagOfWords2VecMN(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
好了,至此我们完成了整个分类器的实现.接下来我们同样适用一个实例,来测试我们的分类器。
7、使用朴素贝叶斯进行垃圾邮件过滤
(1)准备输入数据:我们读取两个邮件文件夹中的内容,并 把其中的每行都切分成可处理的单词。在文件中继续编辑如下代码,实现切分文本。
#该函数将每个句子都解析成单词,并忽略空格,标点符号以及长度小于3的单词 def textParse(bigString): import re listOfTokens=re.split(r'\W*',bigString) return [tok.lower() for tok in listOfTokens if len(tok)>2]
(2)有了可以使用的输入数据类型,接下来我们就可以利用我们之前的算法进行邮件过滤了,继续编辑代码:
#检测垃圾邮件 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=createVocabList(docList) #range(50)表示从0到50,不包括50 trainingSet=range(50) #测试集 testSet=[] #随机抽取是个作为测试集 for i in range(10): #从50个数据集中随机选取十个作为测试集,并把其从训练集中删除 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:" print docList[docIndex] print errorCount print "the error rate is:",float(errorCount)/len(testSet)
测试结果:
经过多次测试,我们发现分类器的分类准确率还是很高了。而且,通过输出结果我们发现大部分时候分类器把垃圾邮件划分到正常邮件中了,这种要比把正常邮件划分为垃圾邮件好得多。
好了,后续的章节还会进行分类器的优化。这一节的内容就已经讲完了。另外一个例子涉及到RSS源就不在这里说了。
总之,希望自己能渐渐进步!
相关推荐
本资源为《机器学习实战》第四章基于概率论的分类方法:朴素贝叶斯学习笔记,资源中总结和输入的所有例程代码,并给出注释。资源免费下载
Python项目案例开发从入门到实战源代码第18章 机器学习案例——基于朴素贝叶斯算法的文本分类.rar
跟着Leo机器学习实战–基于概率论的分类方法:朴素贝叶斯 github https://github.com/LeoLeos/MachineLearningLeo/tree/master/bayes 核心思想 如果我们用p1(x,y)表示数据(x,y)属于类别1的概率,用p2(x,y)表示数据(x,...
贝叶斯分类算法是统计学的一种概率分类方法,朴素贝叶斯分类是贝叶斯分类中最简单的一种。其分类原理就是利 用贝叶斯公式根据某特征的先验概率计算出其后验概率,然后选择具有最大后验概率的类作为该特征所属的类。...
机器学习实战(第四章-朴素贝叶斯-所有代码与详细注解及相关数据文件-python3.7) 机器学习实战(第四章-朴素贝叶斯-所有代码与详细注解及相关数据文件-python3.7)
机器学习基于BERT和朴素贝叶斯算法的新闻文本分类项目源码+数据集(95分以上项目).zip 已获老师指导并通过的高分大作业设计项目,可作为期末大作业和课程设计,纯手打高分项目,小白实战没难度。 机器学习基于BERT...
1、内容概要:本资源主要基朴素贝叶斯算法实现垃圾邮件过滤分类,适用于初学者学习文本分类使用。 2、主要内容:邮件数据集email,email文件夹下有两个文件夹ham和spam,其中ham文件夹下的txt文件为正常邮件,spam...
本代码主要利用Python工具实现朴素贝叶斯分类,简单明了,易于理解
机器学习理论与实战(三)朴素贝叶斯 - 计算机视觉、机器学习朝拜者
机器学习实战,基于概率论的分类方法:朴素贝叶斯 1.使用概率分布进行分类 2.学习朴素贝叶斯分类器 3解析RSS源数据
基于传统机器学习(朴素贝叶斯 逻辑斯蒂回归 lightGBM)实现中文文本分类python源码+文本数据集+项目说明.zip 【项目介绍】 中文文本分类 传统机器学习 目录及文件说明 bert_pretrain存放bert预训练的参数及模型 ...
机器学习实战中,使用朴素贝叶斯过滤垃圾邮件Demo的样本数据。
《机器学习实战》源代码中使用的python2.7 在python3.0中部分是无法使用的,所以这经过了我的调试修改后在python3.0中是可以完美运行的 朴素贝叶斯代码 内含数据样本,便于学习
朴素贝叶斯(二)文本分类朴素贝叶斯的一般流程用python进行文本分类准备数据:从文本中构建词向量训练算法:从词向量计算概率测试算法:朴素贝叶斯分类函数文档词袋模型 朴素贝叶斯的一般流程 (1)收集数据:任何...
1、内容概要:本资源主要基朴素贝叶斯算法实现新闻分类,适用于初学者学习文本分类使用。 2、新闻分类源码实现过程:将数据集划分为训练集和测试集;使用jieba模块进行分词,词频统计,停用词过滤,文本特征提取,将...
作为人工智能核心研究领域之一的机器学习, 其研究动机是为了使计算机系统具有人的学习能力以实现人工智能。 那么, 什么是机器学习呢? 机器学习 (Machine Learning) 是对研究问题进行模型假设,利用计算机...
朴素贝叶斯文章个人网站CSDN知乎Python3《机器学习实战》学习笔记(四):朴素贝叶斯基础篇之言论过滤器Python3《机器学习实战》学习笔记(五):朴素贝叶斯实战篇之新浪新闻分类代码第五章:物流(Logistic回归)...
机器学习实战代码以及数据集 Knn SVM adaboost 逻辑回归 朴素贝叶斯 决策树等代码和注释以及数据集
21世纪以来,在数据和计算能力指数式增长的支持下,机器学习算法在应用中取得了重大突破,如人脸识别、语音识别、自然语言处理、网页搜索、购物推荐、自动化交易等方面都取得了突破性进展,掀起了新一轮的人工智能...
Python实现线性回归、逻辑回归、KNN、SVM、朴素贝叶斯、决策树、K-Means7种机器学习算法的经典案例——亲测可用