贝叶斯分类详解,从条件概率说起
作者:互联网
要想了解贝叶斯分类,我们首先要了解概率论中一个我们在生活中中常用的,却又没有觉察的小知识,条件概率。
条件概率,顾名思义,是在某种条件下或者某个特征下的概率。我们这里不再讨论先验和后验概率,以防大家迷糊。只讨论条件概率,更利于大家理解。
举个例子,假设一个学校里有60%男生和40%女生。女生穿裤子的人数和穿裙子的人数相等,所有男生穿裤子。我们定义两个时间A,B。
其中A={某个学生穿的服装类型},B={某个学生的性别};那么A的样本空间为A={A1:穿裙子,A2:穿裤子};B={B1:男,B2:女}
P(A=“穿裙子”|B=“女生”)=50%,那么这个就是女生穿裙子的概率,也就是在限定一个女生的前提下,她穿裙子的概率是50%。那么我们可以推导一下,利用公式:p(A+B)=p(A)+p(B)-p(AB),那么P(A=“穿裙子”并且B=“女生”) =P(A=“穿裙子”)+P(B=“女生”) - P(A=“穿裙子”+B=“女生”)=0.5*0.4+0.4-0.4=0.2,(用互斥的话,更简单,但是不容易理解),P(B=“女生”)=0.4,P(A=“穿裙子”|B=“女生”) =P(A=“穿裙子”并且B=“女生”) /P(B=“女生”),那么以此类推,我们可以定义出条件概率:P(A|B) =P(AB) /P(B)。
有了以上的知识储备,那么我们在理解贝叶斯算法,就有了理论的基石。对于随机变量W,有K个特征。{w1,...,wk},样本空间{C1,...,Cn},每个样本可以称为Ci类别。对随机变量做一次新的实验,等价于<==>在实际生产中,添加了一个具有K个特征的观测值Obeservtion,O1(o1,...,ok)。那么我们要知道O1的类别,就是要求P(C1|O1(o1,...,ok),...,P(Cn|O1(o1,...,ok)的最大值,也就可以说O1(o1,...,ok)属于哪个类别。这个其实是极大释然思想的体现,一次实验中发生的最大概率是,比如说C5,那么他就是属于这个类。
P(Cn|W(W1,...,Wk))=(P(W(W1,...,Wk)|Cn)*P(Cn))/P(W(W1,...,Wk)),可以简化为求P(Cn)*(P(W1|Cn)...P(Wk|Cn)的最大值。Python实现如下,处理中有些细节,初始值,还有就是计算溢出问题等,用些小技巧处理掉。
from 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'], ['my', '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) # 根据词条列表中的词条是否在文档中出现(出现1,未出现0),将文档转化为词条向量 def setOfWords2Vec(vocabSet, inputSet): returnVec = [0] * len(vocabSet) for word in inputSet: if word in vocabSet: returnVec[vocabSet.index(word)] = 1 else: print('the word: %s is not in my vocabulary! ' % 'word') return returnVec # 训练算法,从词向量计算概率p(w0|ci)...及p(ci) # @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 # 初始化,防止有p(w0|ci)=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 # 朴素贝叶斯分类函数,取log 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 # 分类测试整体函数 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, 'classified as:', classifyNB(thisDoc, p0V, p1V, pAb)) testEntry1 = ['stupid', 'garbage'] thisDoc1 = array(setOfWords2Vec(myVocabList, testEntry1)) print(testEntry1, 'classified as:', classifyNB(thisDoc1, p0V, p1V, pAb)) # def bagOfWords2VecMN(vocabList, inputSet): # returnVec = [0] * len(vocabList) # for word in inputSet: # if word in vocabList: # returnVec[vocabList.index(word)] += 1 # return returnVec if __name__ =="__main__": testingNB()
标签:...,女生,Cn,说起,贝叶斯,详解,word,vocabSet,trainMatrix 来源: https://www.cnblogs.com/zhuangxp2008/p/13890229.html