既然要用到贝叶斯公式,首先给出贝叶斯公式
P(A|B)=P(B|A)P(A)/P(B)
数学含义:
P(A)是先验概率,可以通过计算获得
P(B|A)是条件概率,意识是在A发生的条件下B发生的概率
P(B)是用于归一化的“证据”因子,对于给定的样本B,P(B)与类标记无关
P(A|B)就是后验概率,也是需要我们根据P(B|A),P(A)求的
这个准则有什么用呢?接下来给一个例子
使用朴素贝叶斯进行文档分类
目标是实现自动检测输入的文档是侮辱性词还是非侮辱性词
首先用图来描绘整个过程,和对贝叶斯公式的简单运用
创建训练集:
假如你有6个文档,并且知道他们个属于什么类型(侮辱/一般)词
0表示一般词,1表示侮辱词,首先把这些词汇总在一起构建一个无重复的词库
有了词库以后我们要制作训练集,就要把6六个文档用词向量的形式比表示,怎么做呢?,就用到了无重复的词库,把6个文档分别与词库比较,有就标记为1,无则为0,就得到只有01的矩阵,它的列长与词库的长度相同
这就是训练集,接下来训练
训练过程:
词矩阵:[Wi]
c1表示辱骂型词,c0表示一般词
训练的过程是要求出每一词的条件分布P([wi]|c1),P([wi]|c0)
P([wi]|c1):已知词wi是辱骂性词的条件下,它的概率是多少,概率越高表示它出现的次数越多,表示它越可能是辱骂性词
P([wi]|c0):相同可知
要求这两个条件概率,首先要把训练样本根据已知标签分成两类c1,c0,然后再求每一词出现的概率,所以最后得到两个条件概率矩阵。
得到两个矩阵后,相当于训练好的模型,但怎么实现分类呢?在回顾一下贝叶斯准则
P(cj|[wi])=p([Wi]|c1)*P(c1)/P([wi])
P(cj|[wi]):含义是已知词wi,则它是(侮辱性词/非侮辱性)的概率是多少,这就是我们要求的,求得这个概率就能确定它的分类
[Wi]是词矩阵,且假设每一个词都是相互独立,这样就简化了问题,这也是为什么叫朴素贝叶斯。
p([Wi]|c1) = p(W1|c1)*p(W2|c1)*....p(Wn|c1)
p([Wi]|c0) = p(W1|c0)*p(W2|c0)*....p(Wn|c0)
所以
P(c1|[wi]) = p(W1|c1)*p(W2|c1)*....p(Wn|c1)P(c1)
P(c0|[wi]) = p(W1|c0)*p(W2|c0)*....p(Wn|c0)P(c0)
比较P(c1|[wi]),P(c0|[wi])大小
if P(c1|[wi])>P(c0|[wi])
说明是侮辱性词的概率大
else
是一般性词
测试:
假如输入一个不知道类型的文档,根据上面的词库建立它是词向量,分别与上面的两个条件概率向量相乘,计算条件贝叶斯概率即可
代码:
#coding=utf-8 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‘], [‘mr‘, ‘licks‘, ‘ate‘, ‘my‘, ‘steak‘, ‘how‘, ‘to‘, ‘stop‘, ‘him‘], [‘quit‘, ‘buying‘, ‘worthless‘, ‘dog‘, ‘food‘, ‘stupid‘]] #1代表侮辱性文字,0代表正常言论 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) def setOfWords2Vec(vocabList,inputSet): #构建一个长度和vocabList一样的零向量 returnVec =[0]*len(vocabList) for word in inputSet: if word in vocabList: #如果这个词在词表中有,则词向量中相应位置值设为1 #vocabList.index(word) 返回的是词word在vocabList中的位置下标 returnVec[vocabList.index(word)] = 1 else: print ("the word :%s is not in my Vocabulary" %word) return returnVec #朴素贝叶斯分类器训练trainMaxtrix训练矩阵,trainCategory标签 def trainNB0(trainMaxtrix,trainCategory): #行数 numTrainDocs = len(trainMaxtrix) #列数 numWords = len(trainMaxtrix[0]) #侮辱性文档所占概率P(c1) pAbusive = sum(trainCategory)/float(numTrainDocs) #为了防止其中一个概率为零,导致乘积为零,初始化分子为1,分母为2 p0Num = ones(numWords) p1Num = ones(numWords) p0Denom = 2.0 p1Denom = 2.0 #遍历文档,每一行表示一个文档 for i in range(numTrainDocs): #1表示正常言论文档,否则辱骂言论文档 if trainCategory[i] == 1: #统计每个词出现的次数 p1Num += trainMaxtrix[i] #辱骂词的总个数 p1Denom +=sum(trainMaxtrix[i]) else: p0Num += trainMaxtrix[i] p0Denom +=sum(trainMaxtrix[i]) #p([Wi]|c1) = p(W1|c1)*p(W2|c1)*....p(Wn|c1) 因为相互独立 #p1Vect = p1Num/p1Denom,为了防止许多小数相乘下溢,于是log一下 p1Vect = log(p1Num/p1Denom) #p([Wi]|c0) = p(W1|c0)*p(W2|c0)*....p(Wn|c0) #p0Vect = p0Num/p0Denom p0Vect = log(p0Num/p0Denom) return p0Vect,p1Vect,pAbusive #朴素贝叶斯分类器函数 def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1): #p([Wi]|c1)*P(c1) = P(c1|[wi])*P(w) 根据贝叶斯公式 #P(c1|[wi])意思是已知词wi,则它是(侮辱性词/非侮辱性)的概率是多少 p1 = sum(vec2Classify * p1Vec) + log(pClass1) #p([Wi]|c0)*P(c0) = P(c0|[wi])*P(w) p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1) if p1 > p0: return 1; else: return 0; def testingNB(): listOPosts,listClasses = loadDataSet() myVocabList = createVocabList(listOPosts) print("myVocabList",myVocabList) trainMat = [] #把文档转换成词向量,生成一个二维向量矩阵trainMat for postinDoc in listOPosts: trainMat.append(setOfWords2Vec(myVocabList,postinDoc)) print("trainMat",trainMat) p0V,p1V,pAb = trainNB0(trainMat,listClasses) testEntry = [‘love‘,‘my‘,‘dalmation‘] thisDoc = array(setOfWords2Vec(myVocabList,testEntry)) print(testEntry,‘classified as‘,classifyNB(thisDoc,p0V,p1V,pAb)) testEntry = [‘stupid‘,‘garbage‘] thisDoc = array(setOfWords2Vec(myVocabList,testEntry)) print(testEntry,‘classified as‘,classifyNB(thisDoc,p0V,p1V,pAb))
代码来至机器学习实战,我做了详细的注释,结合上面的图过程可以理解
主要还帮助理解的贝叶斯公式到底是怎么实现分类的。
原文地址:https://www.cnblogs.com/zhxuxu/p/9748414.html