从零开始实战机器学习(3)—朴素贝叶斯算法
来源:互联网 发布:淘宝劲舞团情侣衣服 编辑:程序博客网 时间:2024/05/16 08:26
朴素贝叶斯算法原理其实比较简单,就是基于贝叶斯原理。在此先介绍一下贝叶斯原理。条件概率:P(A|B)就是在B发生的条件下A发生的概率。而P(AB) = P(A|B) *P(B) = P(B|A) *P(A),由此可以推出P(B|A) = [P(A|B) *P(B)]/P(A),这个公式就给出了P(A|B)和P(B|A)之间相互转换的公式。也就是先验概率与后验概率之间的相互转换,这也是贝叶斯学派与频率学派之间最大的区别,频率学派只关注事件本身,不涉及先验概率。下面就进入朴素贝叶斯算法的实现过程,会具体将贝叶斯公式应用到我们的例子中。
首先,生成文档列表,该文档列表由六段组成,并在classVec中将这六段文档分类,1代表侮辱类,0代表非侮辱类。
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,返回一个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
在这里,我们重写贝叶斯准则,
def trainNB0(trainMatrix,trainCategory): numTrainDocs = len(trainMatrix) #计算文档的数目 numWords = len(trainMatrix[0]) #计算每篇文档的长度 pAbusive = sum(trainCategory)/float(numTrainDocs)#计算侮辱性文档的概率,因为侮辱性分类标签是1,所以可以直接累加 p0Num = ones(numWords); p1Num = ones(numWords) #将向量置0,p0Num和p1Num是词向量,下文中将其累加代表着每个词出现的次数。 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 #计算条件概率 return p0Vect,p1Vect,pAbusive
上述代码中还存在一些问题需要修改一下,在使用朴素贝叶斯进行分类时,要计算多个概率的乘积以计算文档所属的类别,即计算p(w0|1)p(w1|1)….p(wn|1),其中若有一个为零则结果为零,为消除这种影响,将初始值置0.5。即:
p0Num = ones(numWords); p1Num = ones(numWords) p0Denom = 2.0; p1Denom = 2.0
另一个问题就是下溢出,当计算p(w0|1)p(w1|1)….p(wn|1)时,由于每个概率都是很小的数,在计算多个乘积最终结果可能会下溢出。取自然对数是个不错的选择,而且不会对结果造成任何影响。
p1Vect = log(p1Num/p1Denom) p0Vect = log(p0Num/p0Denom)
朴素贝叶斯分类函数。vec2Classify*p1Vec得到了所有分类为1的词的对数概率,在对其求和根据对数的运算法则就得到了概率乘积的对数。再加上类别概率的对数,就得到了p(w0|1)p(w1|1)….p(wn|1)p(1) = p(w0,w1,…,wn,1)的对数值。分别比较p0和p1的大小就能判断出这些词是属于哪一类。
def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1): p1 = sum(vec2Classify*p1Vec) + log(pClass1) p0 = sum(vec2Classify*p0Vec) + log(1 - pClass1) if p1 > p0: return 1 else: return 0
定义一个测试函数,分别测试[‘love’,’my’,’dalmation’]和[‘stupid’,’garbage’]两组词。
def testingNB(): dataSet,classVec = loadDataSet() voset = createVocabList(dataSet) trainmat = [] for i in dataSet: trainmat.append(setOfWords2Vec(voset,i)) p0,p1,pAb = trainNB0(trainmat,classVec) testEntry = ['love','my','dalmation'] thisDoc = array(setOfWords2Vec(voset,testEntry)) print testEntry,'classified as:',classifyNB(thisDoc,p0,p1,pAb) testEntry = ['stupid','garbage'] thisDoc = array(setOfWords2Vec(voset,testEntry)) print testEntry,'classified as:',classifyNB(thisDoc,p0,p1,pAb)
测试结果如下所示:
['love', 'my', 'dalmation'] classified as: 0['stupid', 'garbage'] classified as: 1
上述代码中setOfWords2Vec函数采用的是词集模型,即每个单词只出现一次,出现记1,未出现记0,但是实际中每个单词未必只出现一次,故要将词集模型修改为词袋模型(bagOfWords2Vec),其实和词集模型并没有太大不同,只是在计数时将置1改为加1。
def bagOfWords2Vec(vocabList, inputSet): returnVec = [0]*len(vocabList) for word in inputSet: if word in vocabList: returnVec[vocabList.index(word)] += 1 return returnVec
- 从零开始实战机器学习(3)—朴素贝叶斯算法
- 机器学习实战【3】(朴素贝叶斯)
- 机器学习算法-朴素贝叶斯实战
- 机器学习实战-朴素贝叶斯算法
- 机器学习之实战朴素贝叶斯算法
- 机器学习之实战朴素贝叶斯算法
- 机器学习之实战朴素贝叶斯算法
- 机器学习之实战朴素贝叶斯算法
- 《机器学习实战》——朴素贝叶斯算法
- 朴素贝叶斯算法解析-机器学习实战(python)
- 机器学习实战(三)——NaiveBayes朴素贝叶斯算法邮件分类
- 从零开始实战机器学习(1)—K近邻算法
- 从零开始实战机器学习(2)—决策树算法
- 机器学习实战——朴素贝叶斯
- 机器学习实战 朴素贝叶斯
- 机器学习实战-朴素贝叶斯
- 《机器学习实战》--朴素贝叶斯
- 机器学习实战--朴素贝叶斯
- 外观模式
- 华为应用市场 应用版权证书或代理证书怎么填
- UML学习样图
- 点击联系人显示号码
- pjax笔记
- 从零开始实战机器学习(3)—朴素贝叶斯算法
- 2.1.15—线性表— Trapping Rain Water
- 使用 CJSON 在C语言中进行 JSON 的创建和解析的实例讲解
- django 信号用法
- linux C 遍历目录及其子目录 opendir -> readdir -> closedir
- 网卡mac地址
- Spark GraphX 入门实例完整Scala代码
- android使用WebView实现显示360°全景H5页面
- 安卓自定义view基础02-角度与弧度