朴素贝叶斯
优点:在数据较少的情况下仍然有效,可以处理多类别问题;
缺点:对于输入数据的准备方式较为敏感;
适用数据类型:标称型数据。
这里用到的贝叶斯准则:p(c|x,y)=p(x,y|c)*p(c)/p(x,y)
而这个准则可以由我们熟悉的全概率公式推导出来:p(x,y|c) = p((x,y)·c)/p(c)
当然这是站在仅限的大学高数知识所能想到的
贝叶斯准则:
·如果p(c1|x,y)>p(c2|x,y)则属于类别c1;
·如果p(c2|x,y)>p(c1|x,y)则属于类别c2。
朴素的含义:
我们会有疑问,朴素贝叶斯中的朴素是什么意思呢?
每个样本的特征值之间如果有关联,那么这样的数据分析将会变得非常麻烦,于是我们便假设特征之间相互“独立”
文档分类朴素贝叶斯算法的公式:
由于特征独立,于是在使用贝叶斯准则计算p(c|w)=p(w|c)*p(c)/p(w)时
可以简化计算p(w1|ci)p(w2|ci)p(w3|ci)p(w4|ci)p(w5|ci)...
文档分类训练算法python3.6实现:
一开始不理解书上的概率求法,参考网上讨论时,有提出《机器学习实战》书上的分类训练算法有误,于是本渣在此略有修改。
#书上的贝叶斯文档分类算法
def trainNB0(trainMat,trainCategory):
numTrainDocs = len(trainMat)
numWords = len(trainMat[0])
#sum(trainCategory) 这里计算的是分类为1的类别的总数
pAbusive = sum(trainCategory)/float(numTrainDocs)
p0Num = np.ones(numWords)
p1Num = np.ones(numWords)
p0Denom = 2.0;p1Denom = 2.0
for i in range(numTrainDocs):
if trainCategory[i] == 1:
p1Num += trainMat[i]
p1Denom += sum(trainMat[i])
else:
p0Num += trainMat[i]
p0Denom += sum(trainMat[i])
p1Vect = [log(float(x)/p1Denom) for x in p1Num]
p0Vect = [log(float(x)/p0Denom) for x in p0Num] #log不能直接对矩阵进行操作
return p0Vect,p1Vect,pAbusive
#从书上算法可以看出,p1Denom 和 p0Denom都是分类样本中词的总数
#这与之前讨论的贝叶斯准则的公式有出路
#分子分母应该是 一个词出现在分类样本中的样本数 / 分类样本的总数
#欢迎指正!
#本渣修改后的算法
def trainNB1(trainMat,trainCategory):
numTrainDocs = len(trainMat)
numWords = len(trainMat[0])
#sum(trainCategory) 这里计算的是分类为1的类别的总数
sumOfCate1 = sum(trainCategory)
sumOfCate0 = len(trainCategory) - sumOfCate1
pAbusive = sumOfCate1/float(numTrainDocs)
p0Num = np.ones(numWords)
p1Num = np.ones(numWords)
#计算每个词在对应类别中出现的样本数量
for i in range(numTrainDocs):
if trainCategory[i] == 1:
p1Num += trainMat[i]
else:
p0Num += trainMat[i]
#log不能直接对矩阵进行操作
#词出现的样本数与一个分类样本所有样本数量的比
p1Vect = [log(float(x)/sumOfCate1) for x in p1Num]
p0Vect = [log(float(x)/sumOfCate0) for x in p0Num]
return p0Vect,p1Vect,pAbusive
朴素贝叶斯分类算法文档分类python3.6实现:
#朴素贝叶斯分类算法
#p0Vec:好词概率集,p1Vec:坏词概率集,pClass1:坏词率
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 post in listOPosts:
trainMat.append(setOfWord2Vec(myVocabList,post))
p0V,p1V,pC = trainNB0(np.array(trainMat),np.array(listClasses))
testEntry = ['love','my','dalmation']
thisDoc = np.array(setOfWord2Vec(myVocabList,testEntry))
print(testEntry,'classified is:',classifyNB(thisDoc,p0V,p1V,pC))