朴素贝叶斯
优点:在数据较少的情况下仍然有效,可以处理多类别问题;
缺点:对于输入数据的准备方式较为敏感;
适用数据类型:标称型数据。
这里用到的贝叶斯准则: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))