朴素贝叶斯的原理和实现
来源:互联网 发布:java socket聊天程序 编辑:程序博客网 时间:2024/06/08 07:35
概念
朴素贝叶斯(naïveBayes)法是基于贝叶斯定理与特征条件独立假设的分类方法。对于给定的训练数据集,首先基于特征条件独立假设学习输入/输出的联合概率分布;然后基于此模型,对给定的输入x,利用贝叶斯定理求出后验概率最大的输出y。朴素贝叶斯法实现简单,学习与预测的效率都很高,是一种常用的方法。
原理
朴素贝叶斯分类的思想基础:对于给出的待分类项,求解在此项出现的条件下各个类别出现的概率,哪个最大,就认为此待分类项属于哪个类别。
朴素贝叶斯分类的定义:
1. 设x={a1, a2, …, am}为一个待分类项,而每个a为x的一个特征属性。
2. 有类别集合C={y1, y2, …, yn}。
3. 计算P(y1|x), P(y2|x), …, P(yn|x)。
4. 如果P(yk|x)=max{ P(y1|x),P(y2|x),…,P(yn|x)},则x类别为yk。
那么现在的关键就是如何计算第3步中的各个条件概率,我们可以这么做:
1. 找到一个已知分类的待分类项集合,这个集合叫做训练样本集。
2. 统计得到在各类别下各个特征属性的条件概率估计,即:
P(a1|y1), P(a2|y1), …, P(am|y1); …;P(a1|yn), P(a2|yn), …, P(am|yn)
3. 如果各个特征属性是条件独立的,则根据贝叶斯定理有如下推导:
因为分母对于所有类别为常数,因为我们只要将分子最大化即可。朴素贝叶斯法对条件概率分布作了条件独立性的假设。由于这是一个较强的假设,朴素贝叶斯法也由此得名。具体地,条件独立性假设是:
到这里只要选出最大的那个P(yk|x)就是x的类别yk。
一些技巧
拉普拉斯平滑
利用贝叶斯分类器对文档进行分类时,要计算多个概率的乘积,若某一个概率为0,则最后的乘积也为0。为了降低这种影响,可使用拉普拉斯平滑。
在计算p(X|Y)的时候,将分子加上λ,分母加上K*λ,其中K为X可取的值的种类数量,λ=1即为拉普拉斯平滑。
此时有P(X|Y)>0,∑P(X|Y)=1。
下溢问题
多个小概率相乘可能会造成数据下溢得不到正确的答案(四舍五入后都为0)。可以对成绩取对数,即ln(a*b)=ln(a)+ln(b)。
阈值
朴素贝叶斯一个常见的应用是文本分类,如垃圾邮件分类。如果垃圾邮件被分成正常邮件我们还可以接收,但是,如果正常邮件被分成垃圾邮件,就会比较麻烦。所以,可以给这两个分类设置不同的阈值。
如spam=3,ham=1,则p(spam|x)>3p(ham|x),才认为该邮件为垃圾邮件,而p(ham|x)> p(spam|x)则是正常邮件,否则可以视为待定。
文本分类的例子
转自《机器学习实战》
test.py
#coding:utf-8import bayesfrom numpy import *listOposts,listClasses=bayes.loadDataSet()myVocabList=bayes.createVocabList(listOposts)print myVocabList #生成不重复词列表print listOposts[0] #如果出现该词,则对应列表对应位置为1,也就是该文档的特征向量print bayes.setOfWords2Vec(myVocabList,listOposts[0])trainMat=[]for postinDoc in listOposts: trainMat.append(bayes.setOfWords2Vec(myVocabList,postinDoc))for i in range(len(trainMat)): print trainMat[i] #生成所有文档的特征向量p0V,p1V,pAb=bayes.trainNB0(trainMat,listClasses)print pAb #对于所有文档类别为1的概率print p0V #计算词列表类别为0时的概率print p1V #计算词列表类别为1时的概率(转换为log)testEntry = ['love','love','love','love','garbage', 'my', 'dalmation']thisDoc = array(bayes.setOfWords2Vec(myVocabList, testEntry))#生成对应的特征向量print testEntry, '特征向量:',thisDocc = bayes.classifyNB(thisDoc, p0V, p1V, pAb)print "类别为",ctestEntry = ['stupid', 'garbage']thisDoc = array(bayes.setOfWords2Vec(myVocabList, testEntry))print testEntry, '特征向量:',thisDocc = bayes.classifyNB(thisDoc, p0V, p1V, pAb)print "类别为",cbayes.spamTest()#垃圾邮件分类的一个例子
bayes.py
#coding:utf-8from numpy import *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']] classVec = [0,1,0,1,0,1] #对应的分类 return postingList,classVec def createVocabList(dataSet):#创建不重复词列表 vocabSet = set([]) #创建空集 for document in dataSet: vocabSet = vocabSet | set(document)#合并 return list(vocabSet)#输入为词汇表及某个文档,输出为文档向量,向量元素为0或1表示,表示单词在输入文档中是否出现def setOfWords2Vec(vocabList, inputSet): returnVec = [0]*len(vocabList)#创建元素全为0的向量 for word in inputSet: if word in vocabList: returnVec[vocabList.index(word)]= 1 else: print "theword: %s is not in my Vocabulary!" % word return returnVec#输出p(x,y|c0),p(x,y|c1),p(c1)def trainNB0(trainMatrix,trainCategory): numTrainDocs = len(trainMatrix) numWords = len(trainMatrix[0]) pAbusive = sum(trainCategory)/float(numTrainDocs)#计算类别为1占比,多分类需要改一下。 p0Num = ones(numWords); p1Num =ones(numWords) #change to ones() p0Denom = 2.0; p1Denom = 2.0 #change to 2.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 = log(p1Num/p1Denom) #change to log() p0Vect = log(p0Num/p0Denom) #change to log() return p0Vect,p1Vect,pAbusivedef classifyNB(vec2Classify, p0Vec, p1Vec, pClass1): p1 = sum(vec2Classify * p1Vec) +log(pClass1) #element-wise mult p0 = sum(vec2Classify * p0Vec) + log(1.0- pClass1) print "类别1=",p1,"类别0=",p0 if p1 > p0: return 1 else: return 0#文档词袋def bagOfWords2VecMN(vocabList, inputSet): returnVec = [0]*len(vocabList) for word in inputSet: if word in vocabList: returnVec[vocabList.index(word)]+= 1 return returnVec#测试分类def testingNB(): listOPosts,listClasses =loadDataSet() myVocabList =createVocabList(listOPosts) trainMat=[] for postinDoc in listOPosts: trainMat.append(setOfWords2Vec(myVocabList,postinDoc)) p0V,p1V,pAb =trainNB0(array(trainMat),array(listClasses)) testEntry = ['love', 'my', 'dalmation'] thisDoc =array(setOfWords2Vec(myVocabList, testEntry)) print testEntry,'classifiedas: ',classifyNB(thisDoc,p0V,p1V,pAb) testEntry = ['stupid', 'garbage'] thisDoc =array(setOfWords2Vec(myVocabList, testEntry)) print testEntry,'classifiedas: ',classifyNB(thisDoc,p0V,p1V,pAb)def textParse(bigString): #inputis big string, #output is word list import re listOfTokens = re.split(r'\W*', bigString) return [tok.lower() for tokin listOfTokens if len(tok) > 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)#创建词表 trainingSet = range(50);testSet=[] #create test set 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:#trainthe classifier (get probs) trainNB0 trainMat.append(bagOfWords2VecMN(vocabList,docList[docIndex])) trainClasses.append(classList[docIndex]) p0V,p1V,pSpam =trainNB0(array(trainMat),array(trainClasses)) errorCount = 0 for docIndex in testSet: #classify the remaining items wordVector =bagOfWords2VecMN(vocabList, docList[docIndex]) if classifyNB(array(wordVector),p0V,p1V,pSpam)!= classList[docIndex]: errorCount += 1 print "classificationerror",docList[docIndex] print 'the error rate is: ',float(errorCount)/len(testSet)
- 朴素贝叶斯的原理和实现
- 朴素贝叶斯分类和预测算法的原理及实现
- SPARK朴素贝叶斯实现原理
- 朴素贝叶斯原理及实现
- 分类算法-----朴素贝叶斯原理和python实现
- 朴素贝叶斯方法(Naive Bayes)原理和实现
- 朴素贝叶斯算法的实现和应用
- 朴素贝叶斯的实现
- 朴素贝叶斯算法原理及Scala实现
- 朴素贝叶斯原理及Python实现
- 朴素贝叶斯原理及python实现
- 朴素贝叶斯的JAVA实现
- 朴素贝叶斯分类的实现
- 机器学习笔记:朴素贝叶斯方法(Naive Bayes)原理和实现
- 朴素贝叶斯分类的原理与流程
- 朴素贝叶斯分类原理
- 朴素贝叶斯原理
- 朴素贝叶斯原理
- 图形学领域的关键算法及源码链接
- 面向切面编程(AOP)的理解
- 这些优秀的音视频开源框架你值得收藏
- Android 黑科技之让进程不被杀掉
- eclipse debug模式修改change value值
- 朴素贝叶斯的原理和实现
- MySQL数据库:地区表设计及完整5级地区数据
- GraphFrame 实现最小生成树
- 【河南省多校脸萌第六场 E】2358:LLM找对象
- c#中数组有五种声明方式
- android webview 常见的
- 使用 JUnit4参数化的特性来创建Selenium WebDriver的数据驱动测试中遇到的错误
- AngularJS杂记8----部分常用service服务案例详解(持续更新)
- Android开发笔记: 5种对话框案例