在机器学习中,朴素贝叶斯算法对于大家来说其实并不陌生,在我前面的博客中,我也对朴素贝叶斯算法的原理有所介绍,这篇文章我们一起来学习如何用Python来实现这个朴素贝叶斯算法。
首先我们导入numpy这个Python库,来支持我们后续的一些数学运算。
from numpy import *
然后我们定义一个导入数据集的方法,这个数据集是一个有6个维度的向量,其中向量中的内容是若干词语,这些词语是带有感情色彩的,然后classVec中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']]
classVec = [0, 1, 0, 1, 0, 1]
return postingList, classVec
有了导入数据集的方法之后,我们再来创建一个词的集合的方法:
# 创建一个包含在所有文档中出现的不重复词的列表
def createVocabList(dataSet):
vocabSet = set([]) # 创建一个空集
for document in dataSet:
vocabSet = vocabSet | set(document) # 创建两个集合的并集
return list(vocabSet)
然后我们将文档中的词语转化成词向量,这里就涉及到一个词集模型和一个词袋模型,词集模型就相当于是数学中的集合,在同一个文档中,所有的词只能出现一次,词袋模型就相当于是一个袋子中装了许多的词,每个词都可以出现一次或者多次。
def setOfWords2Vec(vocabList, inputSet):
returnVec = [0]*len(vocabList) # 创建一个其中所含元素都为0的向量
for word in inputSet:
if word in vocabList:
# returnVec[vocabList.index(word)] = 1 # index函数在字符串里找到字符第一次出现的位置 词集模型
returnVec[vocabList.index(word)] += 1 # 文档的词袋模型
else: print (the word: %s is not in my Vocabulary!" % word)
return returnVec
我们将词语转换成向量之后,就容易进行数学处理了,下一步我们来定义朴素贝叶斯分类器的训练函数:
def trainNB1(trainMatrix,trainCategory):
numTrainDocs=len(trainMatrix)
numWord=len(trainMatrix[0])
pAbusive=sum(trainCategory)/len(trainCategory)
p0Num=ones(numWord)
p1Num=ones(numWord)# 初始化为1
p0Demon=2
p1Demon=2 #初始化为2
for i in range(numTrainDocs):
if trainCategory[i]==0:
p0Num+=trainMatrix[i]
p0Demon+=sum(trainMatrix[i])
else:
p1Num+=trainMatrix[i]
p1Demon+=sum(trainMatrix[i])
p0Vec=log(p0Num/p0Demon) #对结果求对数
p1Vec=log(p1Num/p1Demon)
return p0Vec,p1Vec,pAbusive
在这里,我们来看看如何利用词向量来计算概率,根据朴素贝叶斯公式,假设这个词向量为:
def classifyNB(vec2Classify,p0Vec,p1Vec,pClass1):
p1=sum(vec2Classify*p1Vec)+log(pClass1)
p0=sum(vec2Classify*p0Vec)+log(1-pClass1)
if p1>p0:
return 1
else:
return 0
有了这个分类器之后,我们创建测试样本来对我们的样本进行分类操作:
def testingNB():
listPosts,listClasses=loadDataSet()
myVocabList=createVocabList(listPosts)
trainMat=[]
for postinDoc in listPosts:
trainMat.append(setOfWords2Vec(myVocabList,postinDoc))
p0V,p1V,pAb=trainNB1(trainMat,listClasses)
testEntry=['love','my','dalmation']
thisDoc=setOfWords2Vec(myVocabList,testEntry)
print(testEntry,'classified as:',classifyNB(thisDoc,p0V,p1V,pAb))
testEntry=['stupid','garbage']
thisDoc=array(setOfWords2Vec(myVocabList,testEntry))
print(testEntry,'classified as:',classifyNB(thisDoc,p0V,p1V,pAb))
最后我们执行这个方法,可以得到分类结果:
['love', 'my', 'dalmation'] classified as: 0 #分类到正常言论
['stupid', 'garbage'] classified as: 1 #分类到侮辱性言论
最后我们可以得到这两组测试样本正确的分类,希望这篇文章对各位朋友对朴素贝叶斯算法的理解有所帮助,如有纰漏,也请各位不吝指教。