naive bayes +python 朴素贝叶斯 python分类实例

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/u010918541/article/details/70880607

朴素贝叶斯 naive bayes 分类实例

首先是贝叶斯定理 P(A|B)=P(B|A)*P(A)/ P(B)

N个独立特征的贝叶斯定理  W是组向量 p(W|C)就可以表示为 p(w0|c)*p(w1|c)*p(w2|c)...*p(wN|c)

这个就是独立特征的概率的意思,比如,明天会下雨的概率是0.5 , 那么明天下雨并且抛硬币向上的概率是多少? 答案就是 p(明天下雨)*p(硬币向上)


正题来了 

我们现在从网站上下了四条有关爱情的名言,四条有关生气的名言,还有两条测试名言,测试属于爱情,还是生气,用贝叶斯公式来表示就是

P(分类|句子名言)=P(句子名言|分类)*P(分类)/P(句子名言)


该句子名言是爱情分类的概率应该为

P(爱情|句子名言)=P(句子名言|爱情)*P(爱情)/P(句子名言)

该句子名言是生气分类的概率应该为

P(生气|句子名言)=P(句子名言|生气)*P(生气)/P(句子名言)

因为右边公式有共同的分母,所以在比较的时候只比较分子大小,就可以判断出来,哪边大,哪边小

若 P(句子名言|爱情)*P(爱情) >  P(句子名言|生气)*P(生气)  则这个名言属于爱情类 ,反之,则是生气类


如何计算P(句子名言|爱情)*P(爱情)的概率呢?

首先我们知道 P(爱情)的概率 P(爱情)=4/(4+4)=0.5  因为我们下载了四条爱情的,四条生气的,所以爱情的是0.5的概率

计算P(句子名言|爱情)的概率可以有不同的模型,我们现在只考虑每个词在文章里面出现的次数,然后计算概率,具体过程是

首先我们创建一个包含所有内容的不重复的词的组合mVocablist

假如我们只下载了两句话 'i love you '爱情类和 'i am angry'生气类, 那么这个组合 mVocablist 是 [‘i’,'love','angry','am','you']

创建训练组合

考虑mVocablist组合中的单词在在某个句子中是否出现,出现为1,不出现为 0,那么这个训练组合应该为

对于爱情类 只有 i love you 三个单词 则组合为train1[1,1,0,0,1] 代表 i love you 出现,am amgry 没有出现

对于生气类 只有 i am angry 三个单词 则组合为train2[1,0,1,1,0] 代表 i am angry 出现 love you 没有出现

计算P(句子名言|爱情)的概率

P(句子名言|爱情)=train1/sum(train1)=[1,1,0,0,1]/3=[0.33,0.33,0,0,0.33]

P(句子名言|生气)=train2/sum(train2)=[1,0,1,1,0]/3=[0.33,0,0.33,,0.33,0]

测定 ‘love ’属于 哪一类

则 love 属于 爱情类的概率如下 因为只有一个词所以

P(爱情|love)=P(love|爱情)*P(爱情)=0.33*0.5=0.165

则 love 属于 生气类的概率如下

P(生气|love)=P(love|生气)*P(生气)=0*0.5=0

0.165>0 则 love 属于爱情类


如果不只是一个词 比如是“ i love"

P(爱情|love,i)=P(love|爱情)*P(i|爱情)*P(爱情)=0.33*0.33*0.5=0.01797

P(生气|love,i)=P(love|生气)*P(i|生气)*P(生气)=0*0.33*0.5=0


一般为避免出现0概率的情况,通常都是设定每个词最低出现为1,在句子中出现多少次,则开始叠加出现的次数,也因为乘积的原因,一般取log 进行运算,避免概率极小时,出现相乘为0 的情况


1,我们现在从网站上下了四条有关爱情的名言,四条有关生气的名言,还有两条测试名言,测试属于爱情,还是分类

dataset=['There is only one love happiness in this life to love and love  be loved',
				'Being deeply loved by love someone gives you strength while loving someone deeply gives you courage',
				'Success is no accident It is hard work perseverance learning studying sacrifice and most of all love of what you are doing or learning to do',
				'Choose a job you love and you will never have to work a day in your life',
				'For every minute you remain angry you give up sixty seconds of peace of mind',
				'When angry count to ten before you speak If very angry count to one hundred',
				'When angry count to four when very angry swear',
				'My uncle Sammy was an angry man He had printed on his tombstone What are you looking at',
				]
classset=[1,1,1,1,0,0,0,0]
testdata=['I m still pretty self-centered greedy and angry',
				  'Love yourself It is important to stay positive because beauty comes from the inside out']

dataset 代表数据集合,classset代表分类1代表爱情分类,0代表生气分类,分类顺序就是dataset里面的顺序 即前四个是爱情,后四个是生气 testdata 是测试数据集

2,数据分割,因为上面的是句子,所以现在我们要将句子分割成全部小写字符的单词,分割完成以后放入两个矩阵中

listofTocken=[]
testofTocken=[]
for i in range(len(dataset)):
	listofTocken.append(dataset[i].lower().split())
for i in range(len(testdata)):
	testofTocken.append(testdata[i].lower().split())
3,创建一个包含不重复单词的词表

#创建一个没有重复词语的词表
mVocablist=bayes.createVocabList(listofTocken)
#创建一个词表 在每个小文档中是否出现的集合 词表词出现为1 不出现为0
trainMat=[]
for words in listofTocken:
	trainMat.append(bayes.setOfWords2Vec(mVocablist,words))
	
#创建测试testMat
testMat=[]
for words in testofTocken:
	testMat.append(bayes.setOfWords2Vec(mVocablist,words))

4,开始训练测试

#需要训练的文章数
numOftrainDocs=len(trainMat)
#每一篇有多少个数据 其实就是词表的个数大小
numwords=len(trainMat[0])
#计算的love quote的概率
pLove=sum(classset)/float(numOftrainDocs)

#初始化两个计算love 和 angry 的数组
ploveNum=ones(numwords) #出现次数初始化为1
pangryNum=ones(numwords) #出现次数初始化为1

ploveDenom=2.0 #初始化概率分母
pangryDenom=2.0

for i in range(numOftrainDocs):
	if classset[i]==1:
		#是love 分组的 这篇文档
		ploveNum+=trainMat[i]
		#此处 ploveNum 是一个向量 [0,0,0,0,0,0,0.....0] traingMat 也是一个向量 [0,0,0,1,0,0,1,0,....0,1,0] 结果还是向量
		ploveDenom+=sum(trainMat[i]) #此处是对traingmat 中1求和 结果是浮点数
	else:
		#是angry 分组的 这篇文档
		pangryNum+=trainMat[i]
		#同上 依然是向量
		pangryDenom+=sum(trainMat[i]) #此处是对traingmat 中1求和 结果是浮点数

ploveVect=log(ploveNum/ploveDenom) #属于love 各个词的概率大小
pangryVect=log(pangryNum/ploveDenom)#属于angty 各个词的概率大小

#print ploveVect,pangryVect
#print '总的love 文档概率 ',pLove

def testNB(doc,ploveV,pangryV,pL):
	plove=sum(doc*ploveV)+log(pL)
	pangry=sum(doc*pangryV)+log(1.0-pL)
	if plove>pangry:
		return "love quote"
	else:
		return "angry quote"
for i  in range(len(testMat)):
	print testdata[i], 'is ',testNB(testMat[i],ploveVect,pangryVect,pLove)

完整代码如下

# -*- coding: utf-8 -*-

from numpy import *

# 创建一个没有重复词表的list
def createVocabList(dataSet):
    vocabSet = set([])  #create empty set
    for document in dataSet:
        vocabSet = vocabSet | set(document) #union of the two sets
    return list(vocabSet)
# 查看词表在每个句子中是否出现
def setOfWords2Vec(vocabList, inputSet):
    returnVec = [0]*len(vocabList)
    for word in inputSet:
        if word in vocabList:
            returnVec[vocabList.index(word)] = 1
    return returnVec


dataset=['There is only one love happiness in this life to love and love  be loved',
				'Being deeply loved by love someone gives you strength while loving someone deeply gives you courage',
				'Success is no accident It is hard work perseverance learning studying sacrifice and most of all love of what you are doing or learning to do',
				'Choose a job you love and you will never have to work a day in your life',
				'For every minute you remain angry you give up sixty seconds of peace of mind',
				'When angry count to ten before you speak If very angry count to one hundred',
				'When angry count to four when very angry swear',
				'My uncle Sammy was an angry man He had printed on his tombstone What are you looking at',
				]
classset=[1,1,1,1,0,0,0,0]
testdata=['I m still pretty self-centered greedy and angry',
				  'Love yourself It is important to stay positive because beauty comes from the inside out']

listofTocken=[]
testofTocken=[]
for i in range(len(dataset)):
	listofTocken.append(dataset[i].lower().split())
for i in range(len(testdata)):
	testofTocken.append(testdata[i].lower().split())
	
#创建一个没有重复词语的词表
mVocablist=createVocabList(listofTocken)
#创建一个词表 在每个小文档中是否出现的集合 词表词出现为1 不出现为0
trainMat=[]
for words in listofTocken:
	trainMat.append(setOfWords2Vec(mVocablist,words))
	
#创建测试testMat
testMat=[]
for words in testofTocken:
	testMat.append(setOfWords2Vec(mVocablist,words))
	
#需要训练的文章数
numOftrainDocs=len(trainMat)
#每一篇有多少个数据 其实就是词表的个数大小
numwords=len(trainMat[0])
#计算的love quote的概率
pLove=sum(classset)/float(numOftrainDocs)

#初始化两个计算love 和 angry 的数组
ploveNum=ones(numwords)
pangryNum=ones(numwords)

ploveDenom=2.0
pangryDenom=2.0

for i in range(numOftrainDocs):
	if classset[i]==1:
		#是love 分组的 这篇文档
		ploveNum+=trainMat[i]
		#此处 ploveNum 是一个向量 [0,0,0,0,0,0,0.....0] traingMat 也是一个向量 [0,0,0,1,0,0,1,0,....0,1,0] 结果还是向量
		ploveDenom+=sum(trainMat[i]) #此处是对traingmat 中1求和 结果是浮点数
	else:
		#是angry 分组的 这篇文档
		pangryNum+=trainMat[i]
		#同上 依然是向量
		pangryDenom+=sum(trainMat[i]) #此处是对traingmat 中1求和 结果是浮点数

ploveVect=log(ploveNum/ploveDenom) #属于love 各个词的概率大小
pangryVect=log(pangryNum/ploveDenom)#属于angty 各个词的概率大小

#print ploveVect,pangryVect
#print '总的love 文档概率 ',pLove

def testNB(doc,ploveV,pangryV,pL):
	plove=sum(doc*ploveV)+log(pL)
	pangry=sum(doc*pangryV)+log(1.0-pL)
	if plove>pangry:
		return "love quote"
	else:
		return "angry quote"
for i  in range(len(testMat)):
	print testdata[i], 'is ',testNB(testMat[i],ploveVect,pangryVect,pLove)

猜你喜欢

转载自blog.csdn.net/u010918541/article/details/70880607