朴素贝叶斯原理
朴素贝叶斯(naive Bayes)算法是有监督的学习算法,解决的是分类问题,如客户是否流失、是否值得投资、信用等级评定等多分类问题。该算法的优点在于简单易懂、学习效率高、在某些领域的分类问题中能够与决策树、神经网络相媲美。但由于该算法以自变量之间的特征独立性和连续变量的正态性假设为前提,就会导致算法精度在某种程度上受影响。
贝叶斯方法把计算 “具有某特征的条件下属于某类” 的概率转换成计算 “属于某类的条件下具有某特征” 的概率,属于有监督学习。
算法优缺点
**优点:**数据较少的情况下仍然有效,可以处理多类别问题
**缺点:**输入的数据有条件限制,精度不高
贝叶斯理论
朴素贝叶斯作为贝叶斯决策理论的一部分,首先先了解一下贝叶斯理论的概念。假设一个数据集,有两类组成。我们现在用p1(x,y)表示数据点(x,y)属于类别1的概率,用p2(x,y)表示数据点(x,y)属于类别2的概率,那么对于一个新数据点(x,y),可以用下面的规则来判断它的类别:
如果p1(x,y) > p2(x,y),那么类别为1
如果p1(x,y) < p2(x,y),那么类别为2
也就是说,我们会选择高概率对应的类别 。这就是贝叶斯决策理论的核心思想,即选择具有最高概率的决策。
理论部分李航老师书中已经讲的很详细,此部分不再赘述。
算法步骤
文本运用
以在线社区留言为例。为了不影响社区的发展,我们要屏蔽侮辱性的言论,所以要构建一个快速过滤器,如果某条留言使用了负面或者侮辱性的语言,那么就将该留言标志为内容不当。过滤这类内容是一个很常见的需求。对此问题建立两个类型:侮辱类和非侮辱类,使用1和0分别表示。
我们把文本看成单词向量或者词条向量 ,也就是说将句子转换为向量。考虑出现所有文档中的单词,再决定将哪些单词纳入词汇表或者说所要的词汇集合,然后必须要将每一篇文档转换为词汇表上的向量。简单起见,我们先假设已经将本文切分完毕,存放到列表中,并对词汇向量进行分类标注。
步骤一:创建文本及标签
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']]
# 类别标签向量,1代表侮辱性词汇,0代表不是
classVec = [0, 1, 0, 1, 0, 1]
return postingList, classVec
postingList,classVec=loadDataSet()
for each in postingList:
print(each)
print(classVec)
['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']
[0, 1, 0, 1, 0, 1]
其中,postingList和classVec分别为切分后的样本和类别标签
步骤二:创建词汇表,转化为词向量
def creatVocablist(data):
vocabset = set([])
for i in data:
vocabset = vocabset|set(i)
print("字典: {}".format(vocabset))
return list(vocabset)
#转换为词向量
def setofWord2Vec(vocabList,inputSet):
returnVec = [0]*len(vocabList)
for word in inputSet:
if word in vocabList:
returnVec[vocabList.index(word)] = 1
else:
print("该词不在词典中")
return returnVec
postinglist,classVec = loadDataSet()
myvocabList = creatVocablist(postingList)
trainMat = []
for word in postingList:
trainMat.append(setofWord2Vec(myvocabList,word))
print("trainMat:\n",trainMat)
字典: {'love', 'has', 'help', 'please', 'stop', 'how', 'steak', 'him', 'to', 'ate', 'garbage', 'licks', 'mr', 'dalmation', 'I', 'dog', 'maybe', 'food', 'park', 'flea', 'buying', 'worthless', 'posting', 'cute', 'so', 'is', 'my', 'not', 'quit', 'problems', 'stupid', 'take'}
trainMat:
[[0, 1, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 0, 0], [0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 1, 1], [1, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 1, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 1, 0], [0, 0, 0, 0, 1, 1, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0], [0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0, 0, 1, 1, 0, 0, 0, 0, 0, 0, 1, 0, 1, 0]]
这里采用的是一种one-hot编码方式,如果词语出现在词表中,则在词表位置标记为1,这种方法虽然简便,但是并未考虑词语的顺序。
步骤三:创建贝叶斯分类器
import numpy as np
def trainNBO(trainMtrix,trainCategory):
numTrainDocs = len(trainMtrix)#文档数目
numWords = len(trainMtrix[0])#每篇文档的字数
pAbusive = sum(trainCategory)/numTrainDocs #侮辱类概率
#创建numpy.zeros数组
p0Num=np.zeros(numWords);p1Num=np.zeros(numWords)
#分母初始化为0.0
p0Denom=0.0;p1Denom=0.0
#分别计算属于侮辱类和非侮辱类的概率
for i in range(numTrainDocs):
if trainCategory[i] == 1:
p1Num += trainMtrix[i]
p1Denom += sum(trainMtrix[i])
else:
p0Num += trainMtrix[i]
p0Denom += sum(trainMtrix[i])
#相除
p1Vect=p1Num/p1Denom #侮辱类的条件概率数组
p0Vect=p0Num/p0Denom #非侮辱类的条件概率数组
return p1Vect,p0Vect,pAbusive
p1V,p0V,pAb = trainNBO(trainMat,classVec)
print('侮辱类概率数组:\n',p1V)
print('非侮辱类概率数组:\n',p0V)
print('所有文档中侮辱类样本所占比率:\n',pAb)
侮辱类概率数组:
[0. 0. 0. 0. 0.05263158 0.
0. 0.05263158 0.05263158 0. 0.05263158 0.
0. 0. 0. 0.10526316 0.05263158 0.05263158
0.05263158 0. 0.05263158 0.10526316 0.05263158 0.
0. 0. 0. 0.05263158 0.05263158 0.
0.15789474 0.05263158]
非侮辱类概率数组:
[0.04166667 0.04166667 0.04166667 0.04166667 0.04166667 0.04166667
0.04166667 0.08333333 0.04166667 0.04166667 0. 0.04166667
0.04166667 0.04166667 0.04166667 0.04166667 0. 0.
0. 0.04166667 0. 0. 0. 0.04166667
0.04166667 0.04166667 0.125 0. 0. 0.04166667
0. 0. ]
所有文档中侮辱类样本所占比率:
0.5