朴素贝叶斯分类算法
算法简介
朴素贝叶斯是使用贝叶斯的条件概率来做分类判断的一种算法,具体的依据就是,对于二分类来说的话,如果
p(y1|x1,x2) > p(y2|x1,x2)
也就是在x1,x2同时发生的情况下,y1发生的概率大于y2发生的概率,由极大似然法可知,我们就有理由相信该x1,x2的样本属于y1分类,但是从数据的角度来看的话,我们一般不能直接得到p(y1|x1,x2) 和 p(y2|x1,x2),这时我们可以考虑一下贝叶斯的条件概率公司,即:
p(y1|x1,x2) = p(x1,x2|y1)p(y1)/p(x1,x2)
p(y2|x1,x2) = p(x1,x2|y2)p(y2)/p(x1,x2)
其中等式右边各个变量的计算方式如下,注意朴素贝叶斯公式中的朴素就是默认各个特征变量之间是相互独立的即,p(x1,x2)=p(x1)*p(x2):
- p(y1),p(y2)分别为分类为y1,y2的概率,也就是全部样本中y1和y2分别占的个数
p(y1) = Σy1/n # 样本中y1分类的个数/总个数
p(y2) = Σy2/n # 样本中y2分类的个数/总个数
- p(x1,x2|y1)也就是分类为y1的样本中,x1=a,x2=b的个数占y1分类的比例
p(x1,x2|y1) = p(x1|y1)*p(x2|y1)
p(x1|y1)也就是y1分类中x1站全部x的比例,对于python来说乘法的计算,所以我们可以转成对数的计算即:
log(p(x1|y1)*p(x2|y1)) = log(p(x1|y1)) + log(p(x2|y1))
- 因为我们需要对比的是两个数的大小,所以我们可以忽略掉p(x1,x2)的值的大小计算
约去不等式两边的公因数,也就是最后的计算公式可以变成:
Σ(x1,x2|y1) > Σ(x1,x2|y2)
这两个值的比较了,这个式子的含义就是y1分类中
python实现算法的具体思路
以二分类文档来举例
- 我们需要先把文档转化成词向量,如下
testNbX = [[1,0,2,1,0,0,0],[1,0,2,1,0,0,0],[1,0,2,1,0,0,0],[1,0,2,1,0,0,0]]
testNbY = [1,0,1,1]
- 计算每个参数概率
def trainNb(testNbX, testNbY):
p0Num = numpy.ones(len(testNbX[0])) # p(x|y1)的分子
p1Num = numpy.ones(len(testNbX[0])) # p(x|y2)的分子
p0Doman = 2.0 # 计算总共的单词个数也就是总共的特征个数,作为p(x|y1)的分母
p1Doman = 2.0 # 计算总共的单词个数也就是总共的特征个数,作为p(x|y2)的分母
p0YNum = 0 # 分类为0的个数
p1YNum = 0 # 分类为1的个数
for i in range(len(testNbY)):
if testNbY[i] == 1:
p0Num += testNbX[i]
p0Doman += sum(testNbX[i])
p0YNum += 1
else:
p1Num += testNbX[i]
p1Doman += sum(testNbX[i])
p1YNum += 1
p0X = numpy.log(p0Num/p0Doman)
p1X = numpy.log(p1Num/p1Doman)
p0Y = numpy.log(p0YNum/len(testNbY))
p1Y = numpy.log(1-p0Y)
return p0X, p1X, p0Y, p1Y
- 对于一个测试样本,计算它的出现概率,然后确定是属于哪个分类
def classifyNb(vocals, p0X, p1X, p0Y, p1Y):
p0 = sum(vocals * p0X) + p0Y # vocals * p0X, 计算当前单词向量对应的概率,如果该单词出现的次数比较多的话,那么他出现的概率就较大
p1 = sum(vocals * p1X) + p1Y
if ( p0 > p1 ):
return 0
else:
return 1
- 通过调用这三个式子就可以得到通过贝叶斯得到的分类预测