基于概率论的分类方法:朴素贝叶斯,之所以称为”朴素”,是因为整个分类过程之做最原始最简单的假设。分类器根据比较p(Ci|A)条件概率做出分类,其中p(Ci|A)是待分类的A属于类Ci的概率大小。一种有效的计算该条件概率的方法称为贝叶斯准则,即通过下式计算:p(Ci|A)= p(A|Ci)p(Ci)/p(A) 通过比较不同类的p(Ci|A)大小做出选择。朴素贝叶斯的假设每个特征值是相互独立的,且每个特征值同等重要。
朴素贝叶斯的一般过程:
(1)收集数据:可以使用任何方法
(2)准备数据:需要数值型和布尔型
(3)分析数据:当特征值很多时,使用直方图效果更好
(4)训练算法:计算不同独立特征值的概率
(5)测试算法:计算错误率
(6)使用算法:一个常用的应用是文档分类
p(Ci|A)= p(A|Ci)p(Ci)/p(A) 中如果把A看成n个多个独立特征值构成的向量,那么
p(A|Ci)=p(A1|Ci)*p(A2|Ci)*p(A3|Ci)**p(An|Ci)就大大简化了计算过程。
下面附上计算条件概率p(A|Ci)的朴素贝叶斯训练函数和测试函数
#训练函数
def trainNB0(trainMatrix,trainCategory):#trainMatrix为训练文档的词向量矩阵,trainCategory为训练文档的类别
numTrainDocs = len(trainMatrix)
numWords = len(trainMatrix[0])
pAbusive = sum(trainCategory)/float(numTrainDocs)
p0Num = ones(numWords); p1Num = ones(numWords) #拉普拉斯修正
p0Denom = 2.0; p1Denom = 2.0 #拉普拉斯修正
for i in range(numTrainDocs):
if trainCategory[i] == 1: #计算p(A|C1)
p1Num += trainMatrix[i]
p1Denom += sum(trainMatrix[i])
else:
p0Num += trainMatrix[i] #计算p(A|C0)
p0Denom += sum(trainMatrix[i])
p1Vect = log(p1Num/p1Denom) #为了防止下溢出取自然对数
p0Vect = log(p0Num/p0Denom) #为了防止下溢出取自然对数
return p0Vect,p1Vect,pAbusive #返回每个特征值属于类1和类0的条件概率向量,每个类的概率
#分类函数
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1): #vec2Classify为待分类的文档词向量
p1 = sum(vec2Classify * p1Vec) + log(pClass1) #element-wise mult
p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1)
if p1 > p0:
return 1
else:
return 0
代码中出现的词向量vec2Classify形如(1,0,0,1,0…1)代表词汇表(特征向量表)中某特征词在文档中出现与否,1代表出现,0代表未出现,这种词向量只统计词汇出现与否,被描述为词集模型。
另一种词向量形如(2,0,3…1,0)代表词汇表中特征词出现的次数,这种词向量统计词汇的出现次数被描述为词袋模型。
朴素贝叶斯分类器的特征值独立的假设,降低了对数据量的要求,当然这个假设过于简单,条件独立性的假设并不正确,但是朴素贝叶斯分类器任然是一种有效的分类器。