朴素贝叶斯也是一个强大的分类算法。其基本原理:假设现在有1,2,3,3种类别,现有一个数据a,其属于这个3种类别的概率分别为 p1(a),p2(a),p3(a) 。如果这3个概率中 p1(a) 最大,那么就把数据a归为1类。
这道理好简单啊,就算我们猜谜语也会猜一个可能性最大的嘛~~~
果然很朴素啊,但是呢,这里还是有一个问题的,这里的3个概率是怎么计算出来的呢?
为了计算概率,就得翻出概率论的知识了。
假设现有数据 w=w0+w1+...+wn ,好多维啊。。类别有 c={c1,c2} 2种类别。
那么属于c1,c2的概率就可以表示为:
p(c1|w)=p(w|c1)p(c1)p(w)
p(c2|w)=p(w|c2)p(c2)p(w)
如果:
p(c1|w)>p(c2|w) , 那么w属于c1类。
p(c1|w)<p(c2|w) , 那么w属于c2类。
推广到多个类别:
Ok,顺利得到 p(w|ci)p(ci) 。我们就可以比较 p(ci|w) 大小来归类了。
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']]
classvec=[0,1,0,1,0,1]
return postingList,classvec
#生成一个文本集合,包含所有出现的词
def createvocalist(dataSet):
vocaset=set([])
for document in dataSet:
vocaset=vocaset | set(document)
return list(vocaset)
#把每个文档的词对应文本集合,映射成向量,如:[1,0,1,0,0...]
def setofWord2vec(vocalist,inputSet):
returnVec=[0]*len(vocalist)
for word in inputSet:
if word in vocalist:
returnVec[vocalist.index(word)] =1
else:
print "the word : %s is not in ..." % word
return returnVec
def trainNB0(trainMatrix,trainclass):
numdocs=len(trainMatrix)
numWords=len(trainMatrix[0])
#trainclass只有 0,1数据,求和相当于计算A=1的数量,再除以总数就是pA
pA=sum(trainclass)/float(numdocs)
p1num=ones(numWords)
p0num=ones(numWords)
p1sum=2.0
p0sum=2.0
for i in range(numdocs):
if trainclass[i] == 1:
p1num+=trainMatrix[i]#计算单个词出现的数量
p1sum+=sum(trainMatrix[i])#计算所有词出现的数量
else:
p0num+=trainMatrix[i]
p0sum+=sum(trainMatrix[i])
p1vec=log(p1num/p1sum)#这里相当于前面分子左边的部分,在c1类别下,wi出现的概率
p0vec=log(p0num/p0sum)
return p0vec,p1vec,pA
def classifyNB(vec2class,p0Vec,p1Vec,pClass):
#这里的求和有点奇怪,因为按照公式是所有词出现的概率相乘,然而这里却是求和,是因为前面用log来计算了。
p1=sum(vec2class*p0Vec)+log(pClass)
p0=sum(vec2class*p1Vec)+log(1.0-pClass)
if p1>p0:
return 1
else:
return 0
#测试分类
def testingNb():
listdoc,listclass=loadDataSet()
allwordlist=createvocalist(listdoc)
trainMat=[]
for doc in listdoc:
trainMat.append(setofWord2vec(allwordlist,doc))
p0v,p1v,pA=trainNB0(trainMat,listclass)
testdoc=['love','my','jack']
testdocvec=setofWord2vec(allwordlist,testdoc)
print testdoc,'classified as:',classifyNB(testdocvec,p0v,p1v,pA)
参考:
《机器学习实战》