开启掘金成长之旅!这是我参与「掘金日新计划 · 12 月更文挑战」的第12天,点击查看活动详情
一、实验目的
1、理解条件概率、全概率和贝叶斯概率;
2、掌握朴素贝叶斯分类算法;
3、能熟练运用Python编写程序实现朴素贝叶斯分类。
二、实验要求
1、读代码,学python。要求能读懂所给代码,能改写代码实现其它类似算法;
2、运行结果要截图并对结果做分析;
3、所有内容汇总到本文档,无需提供.py文件;
4、文件命名方式:学号+姓名+实验二朴素贝叶斯算法.doc
三、实验内容
1. 阅读代码,为代码添加注释。
2. 改写代码实现文本分类功能
以在线社区的留言板为例。为了不影响社区的发展,我们要屏蔽侮辱性的言论,所以要构建一个快速过滤器,如果某条留言使用了负面或者侮辱性的语言,那么就将该留言标识为内容不当。过滤这类内容是一个很常见的需求。对此问题建立两个类别:侮辱类和非侮辱类,使用1和0分别表示。
四、实验过程(原理,源码)
贝叶斯决策理论原理:
1. 阅读代码,为代码添加注释。
要做的是垃圾邮件过滤,首先需要将邮件进行解析为字符串列表
- """
- 函数说明:接收一个大字符串并将其解析为字符串列表
- """
- def textParse(bigString): #将字符串转换为字符列表
- #listOfTokens = re.split(r'W', bigString)
- listOfTokens = re.split(r'W+', bigString) #将特殊符号作为切分标志进行字符串切分,即非字母、非数字
- return [tok.lower() for tok in listOfTokens if len(tok) > 2] #除了单个字母,例如大写的I,其它单词变成小写
在进行读取邮件后,将字符串转换成字符串列表,然后需要一个函数将切分的词条整理成不重复的词条列表,即返回一个词汇表
1. """
2. createVocabList函数说明:将切分的实验样本词条整理成不重复的词条列表
3. Parameters:
4. dataSet - 整理的样本数据集
5. Returns:
6. vocabSet - 返回不重复的词条列表,也就是词汇表
7. """
8. def createVocabList(dataSet):
9. vocabSet = set([]) #创建一个空的不重复列表
10. for document in dataSet:
11. vocabSet = vocabSet | set(document) #取并集
12. return list(vocabSet)
然后需要根据返回的词汇表,进行构建词袋模型(词袋模型将一段文本看成一系列单词的集合,由于单词很多,故而这段文本就相当于一个袋子,里面装着一系列单词)
- """
- 函数说明:根据vocabList词汇表,构建词袋模型
- Parameters:
- vocabList - createVocabList返回的列表
- inputSet - 切分的词条列表
- Returns:
- returnVec - 文档向量,词袋模型
- """
- def bagOfWords2VecMN(vocabList, inputSet):
- returnVec = [0]len(vocabList) #创建一个其中所含元素都为0的向量
- for word in inputSet: #遍历每个词条
- if word in vocabList:
- returnVec[vocabList.index(word)] += 1 #如果词条存在于词汇表中,则计数加一
- return returnVec #返回词袋模型
下面是贝叶斯分类的训练函数
- """
- trainNB0函数说明:朴素贝叶斯分类器训练函数
- Parameters:
- trainMatrix - 训练文档矩阵
- trainCategory - 训练类别标签向量
- Returns:
- p0Vect - 正常邮件类的条件概率数组
- p1Vect - 垃圾邮件类的条件概率数组
- pAbusive - 文档属于垃圾邮件类的概率
- """
- def trainNB0(trainMatrix,trainCategory):
- numTrainDocs = len(trainMatrix) #计算训练的文档数目
- numWords = len(trainMatrix[0]) #计算每篇文档的词条数
- pAbusive = sum(trainCategory)/float(numTrainDocs) #文档属于垃圾邮件类的概率
- p0Num = np.ones(numWords)
- p1Num = np.ones(numWords) #创建numpy.ones数组,词条出现数初始化为1,拉普拉斯平滑
- p0Denom = 2.0
- p1Denom = 2.0 #分母初始化为2 ,拉普拉斯平滑
- for i in range(numTrainDocs):
- if trainCategory[i] == 1: #统计属于侮辱类的条件概率所需的数据,即P(w0|1),P(w1|1),P(w2|1)···
- p1Num += trainMatrix[i]
- p1Denom += sum(trainMatrix[i])
- else: #统计属于非侮辱类的条件概率所需的数据,即P(w0|0),P(w1|0),P(w2|0)···
- p0Num += trainMatrix[i]
- p0Denom += sum(trainMatrix[i])
- p1Vect = np.log(p1Num/p1Denom) #取对数,防止下溢出
- p0Vect = np.log(p0Num/p0Denom) #取对数,防止下溢出
- return p0Vect,p1Vect,pAbusive #返回属于正常邮件类的条件概率数组,属于侮辱垃圾邮件类的条件概率数组,文档属于垃圾邮件类的概率
然后是贝叶斯分类的测试函数
- """
- classifyNB函数说明:朴素贝叶斯分类器分类函数
- Parameters:
- vec2Classify - 待分类的词条数组
- p0Vec - 正常邮件类的条件概率数组
- p1Vec - 垃圾邮件类的条件概率数组
- pClass1 - 文档属于垃圾邮件的概率
- Returns:
- 0 - 属于正常邮件类
- 1 - 属于垃圾邮件类
- """
- def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
- p1 = sum(vec2Classify p1Vec) + np.log(pClass1) #element-wise mult
- p0 = sum(vec2Classify p0Vec) + np.log(1.0 - pClass1)
- if p1 > p0:
- return 1
- else:
- return 0
最后是测试朴素贝叶斯分类的效果,使用朴素贝叶斯进行交叉验证。使用40个数据为训练集,10个数据为测试集进行测试。
- """
- 函数说明:测试朴素贝叶斯分类器,使用朴素贝叶斯进行交叉验证
- """
- def spamTest():
- docList=[]; classList = []; fullText =[]
- for i in list(range(1,26)): #遍历25个txt文件
- wordList = textParse(open('email/spam/%d.txt' % i,encoding='ISO-8859-1').read()) #读取每个垃圾邮件,并字符串转换成字符串列表
- docList.append(wordList)
- fullText.extend(wordList)
- classList.append(1) #标记垃圾邮件,1表示垃圾文件
- wordList = textParse(open('email/ham/%d.txt' % i,encoding='ISO-8859-1').read()) #读取每个非垃圾邮件,并字符串转换成字符串列表
- docList.append(wordList)
- fullText.extend(wordList)
- classList.append(0) #标记正常邮件,0表示正常文件
- vocabList = createVocabList(docList) #创建词汇表,不重复
- trainingSet = list(range(50)); testSet=[] #创建存储训练集的索引值的列表和测试集的索引值的列表
- for i in list(range(10)): #从50个邮件中,随机挑选出40个作为训练集,10个做测试集
- randIndex = int(np.random.uniform(0,len(trainingSet))) #随机选取索索引值
- testSet.append(trainingSet[randIndex]) #添加测试集的索引值
- del(trainingSet[randIndex]) #在训练集列表中删除添加到测试集的索引值
- trainMat=[]; trainClasses = [] #创建训练集矩阵和训练集类别标签系向量
- for docIndex in trainingSet: #遍历训练集
- trainMat.append(bagOfWords2VecMN(vocabList, docList[docIndex])) #将生成的词集模型添加到训练矩阵中
- trainClasses.append(classList[docIndex]) #将类别添加到训练集类别标签系向量中
- p0V,p1V,pSpam = trainNB0(np.array(trainMat),np.array(trainClasses)) #训练朴素贝叶斯模型
- errorCount = 0 #错误分类计数
- for docIndex in testSet: #遍历测试集
- wordVector = bagOfWords2VecMN(vocabList, docList[docIndex]) #测试集的词集模型
- if classifyNB(np.array(wordVector),p0V,p1V,pSpam) != classList[docIndex]: #如果分类错误
- errorCount += 1 # 错误计数加1
- print ("分类错误的测试集:",docList[docIndex])
- print ('错误率: ',float(errorCount)/len(testSet))
下图为运行结果
2. 改写代码实现文本分类功能
以在线社区的留言板为例。为了不影响社区的发展,我们要屏蔽侮辱性的言论,所以要构建一个快速过滤器,如果某条留言使用了负面或者侮辱性的语言,那么就将该留言标识为内容不当。过滤这类内容是一个很常见的需求。对此问题建立两个类别:侮辱类和非侮辱类,使用1和0分别表示。
大体思路跟邮件拦截是一样的
首先创建一些数据样本作为训练集,并给出标签0/1
- """
- loadDataSet函数说明: 创建一些实验样本
- Returns:
- postingList - 原始的词条列表
- classVec - 类别标签向量
- """
- 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] #1 代表侮辱性文字, 0 代表正常言论
- return postingList,classVec
第二个函数是将样本整理承不重复的词条列表,与第一个例子中的函数一样
- """
- createVocabList函数说明:将切分的实验样本词条整理成不重复的词条列表
- Parameters:
- dataSet - 整理的样本数据集
- Returns:
- vocabSet - 返回不重复的词条列表,也就是词汇表
- """
- def createVocabList(dataSet): #创建一个包含在所有文档中的不重复词的列表
- vocabSet = set([]) #创建一个空集
- for document in dataSet:
- vocabSet = vocabSet | set(document) # “ |”代表创建两个集合的并集
- return list(vocabSet)
然后是根据上面返回的词汇表构建词袋模型
- """
- 函数说明:根据vocabList词汇表,构建词袋模型
- Parameters:
- vocabList - createVocabList返回的列表
- inputSet - 切分的词条列表
- Returns:
- returnVec - 文档向量,词袋模型
- """
- def bagOfWords2Vec(vocabList, inputSet): #创建一个其中所含元素为0的向量
- returnVec = [0]len(vocabList)
- for word in inputSet:
- if word in vocabList:
- returnVec[vocabList.index(word)] += 1
- return returnVec
下面是贝叶斯分类的训练算法
- """
- trainNB0函数说明:朴素贝叶斯分类器训练函数
- Parameters:
- trainMatrix - 训练文档矩阵,即bagOfWords2Vec返回的returnVec构成的矩阵
- trainCategory - 训练类别标签向量,即loadDataSet返回的classVec
- Returns:
- p0Vect - 正常邮件类的条件概率数组
- p1Vect - 垃圾邮件类的条件概率数组
- pAbusive - 文档属于垃圾邮件类的概率
- """
- def trainNB0(trainMatrix,trainCategory):#输入参数为文档矩阵trainMatrix,和每篇文档类别标签所构成的向量trainCategory
- numTrainDocs = len(trainMatrix)
- numWords = len(trainMatrix[0])
- pAbusive = sum(trainCategory)/float(numTrainDocs)
- p0Num = zeros(numWords); p1Num = zeros(numWords) #初始化概率
- p0Denom = 0.0; p1Denom = 0.0
- for i in range(numTrainDocs):
- if trainCategory[i] == 1:
- p1Num += trainMatrix[i]
- p1Denom += sum(trainMatrix[i])
- else:
- p0Num += trainMatrix[i]
- p0Denom += sum(trainMatrix[i])
- p1Vect = p1Num/p1Denom #change to log()
- p0Vect = p0Num/p0Denom #change to log()
- return p0Vect,p1Vect,pAbusive
然后是贝叶斯分类的测试算法
- """
- classifyNB函数说明:朴素贝叶斯分类器分类函数
- Parameters:
- vec2Classify - 待分类的词条数组
- p0Vec - 正常邮件类的条件概率数组
- p1Vec - 垃圾邮件类的条件概率数组
- pClass1 - 文档属于垃圾邮件的概率
- Returns:
- 0 - 属于正常邮件类
- 1 - 属于垃圾邮件类
- """
- def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
- p1 = sum(vec2Classify p1Vec) + log(pClass1)
- p0 = sum(vec2Classify p0Vec) + log(1.0 - pClass1) #2分类问题可以用1.0-pClass1,多分类需要修改
- if p1 > p0:
- return 1
- else:
- return 0
最后是贝叶斯分类器,对文本进行分类预测
-
"""
-
函数说明:测试朴素贝叶斯分类器,使用朴素贝叶斯进行交叉验证
-
0 - 属于正常邮件类
-
1 - 属于垃圾邮件类
-
"""
-
def testingNB():
-
listOPosts, listClasses = loadDataSet()
-
myVocabList = createVocabList(listOPosts)
-
trainMat = []
-
for postinDoc in listOPosts:
-
trainMat.append(bagOfWords2Vec(myVocabList, postinDoc))
-
p0V, p1V, pAb = trainNB0(array(trainMat), array(listClasses))
-
testEntry = ['love', 'my', 'dalmation']
-
thisDoc = array(bagOfWords2Vec(myVocabList, testEntry))
-
print(testEntry, 'classified as: ', classifyNB(thisDoc, p0V, p1V, pAb))
-
testEntry = ['stupid', 'garbage']
-
thisDoc = array(bagOfWords2Vec(myVocabList, testEntry))
-
print(testEntry, 'classified as: ', classifyNB(thisDoc, p0V, p1V, pAb))
对两组词汇进行分类预测,判断其为正常词汇或侮辱词汇
0 - 属于正常邮件类
1 - 属于垃圾邮件类
下图为运行结果:
五、实验总结(困难,收获)
本次实验完成了两个任务,一是阅读老师给的代码并注释,二是理解朴素贝叶斯原理并改写代码完成测试。
首先,在阅读老师给的实验代码时,setOfWords2Vec函数的代码并没有找到在全局中的调用,并将该段代码进行注释后运行源代码,仍然得到正常的实验结果,猜测为不必要函数,将其进行了删除,后面发现该函数与bagOfWords2VecMN函数作用类似,采用的是bagOfWords2VecMN函数。在阅读贝叶斯训练函数时,觉得有一点绕,读起来很吃力,通过百度相关知识,并结合手动测试,解决了该问题。
再修改原有代码时,不知道还可以做什么,通过百度找到的相关实验为直接使用封装好的贝叶斯函数,由于不清楚已经封装好的函数内部结构,未采用找到的几个贝叶斯实验。然后找到一个文本分类的题目,感觉跟邮件识别原理相似,遂决定改善代码完善该实验。
六、附录(源代码)
邮件识别代码及注释
_# from numpy import *
_import numpy as np
import re
"""
createVocabList函数说明:将切分的实验样本词条整理成不重复的词条列表Parameters:
dataSet - 整理的样本数据集****Returns:
vocabSet - 返回不重复的词条列表,也就是词汇表**
"""
def createVocabList(dataSet):
vocabSet = set([]) _#__创建一个空的不重复列表
_for** document in dataSet:
vocabSet = vocabSet | set(document) _#__取并集
_return list(vocabSet)
"""
trainNB0函数说明:朴素贝叶斯分类器训练函数Parameters:
trainMatrix - 训练文档矩阵,即setOfWords2Vec返回的returnVec构成的矩阵****trainCategory - 训练类别标签向量,即loadDataSet返回的****classVec
Returns:
p0Vect - 正常邮件类的条件概率数组****p1Vect - 垃圾邮件类的条件概率数组****pAbusive - 文档属于垃圾邮件类的概率**
"""
def trainNB0(trainMatrix,trainCategory):
numTrainDocs = len(trainMatrix) _#__计算训练的文档数目
_numWords = len(trainMatrix[0]) _#__计算每篇文档的词条数
_pAbusive = sum(trainCategory)/float(numTrainDocs) _#__文档属于垃圾邮件类的概率
_p0Num = np.ones(numWords)
p1Num = np.ones(numWords) _#创建__numpy.ones__数组,__词条出现数初始化为__1,__拉普拉斯平滑
_p0Denom = 2.0
p1Denom = 2.0 _#__分母初始化为__2 ,__拉普拉斯平滑
_for** i in range(numTrainDocs):
if trainCategory[i] == 1: _#__统计属于侮辱类的条件概率所需的数据,即__P(w0|1),P(w1|1),P(w2|1)···
_p1Num += trainMatrix[i]
p1Denom += sum(trainMatrix[i])
else: _#__统计属于非侮辱类的条件概率所需的数据,即__P(w0|0),P(w1|0),P(w2|0)···
_p0Num += trainMatrix[i]
p0Denom += sum(trainMatrix[i])
p1Vect = np.log(p1Num/p1Denom) _#__取对数,防止下溢出
_p0Vect = np.log(p0Num/p0Denom) _#__取对数,防止下溢出
_return p0Vect,p1Vect,pAbusive _#__返回属于正常邮件类的条件概率数组,属于侮辱垃圾邮件类的条件概率数组,文档属于垃圾邮件类的概率
_"""
classifyNB函数说明:朴素贝叶斯分类器分类函数Parameters:
vec2Classify - 待分类的词条数组****p0Vec - 正常邮件类的条件概率数组****p1Vec - 垃圾邮件类的条件概率数组****pClass1 - 文档属于垃圾邮件的概率****Returns:
0 - 属于正常邮件类****1 - 属于垃圾邮件类**
"""
**def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
p1 = sum(vec2Classify * p1Vec) + np.log(pClass1) _#element-wise mult
_p0 = sum(vec2Classify * p0Vec) + np.log(1.0 - pClass1)
if p1 > p0:
return 1
else:
return 0
"""
函数说明:根据vocabList词汇表,构建词袋模型
Parameters:
vocabList - createVocabList返回的列表inputSet - 切分的词条列表****Returns:
returnVec - 文档向量**,词袋模型
"""
def bagOfWords2VecMN(vocabList, inputSet):
returnVec = [0]*len(vocabList) _#__创建一个其中所含元素都为__0__的向量
_for** word in inputSet: _#__遍历每个词条
_if word in vocabList:
returnVec[vocabList.index(word)] += 1 _#__如果词条存在于词汇表中,则计数加一
_return returnVec _#__返回词袋模型
_"""
函数说明:接收一个大字符串并将其解析为字符串列表
"""
def textParse(bigString): _#__将字符串转换为字符列表
__#listOfTokens = re.split(r'\W*', bigString)
_listOfTokens = re.split(r'\W+', bigString) _#__将特殊符号作为切分标志进行字符串切分,即非字母、非数字
_return [tok.lower() for tok in listOfTokens if len(tok) > 2] _#除了单个字母,例如大写的__I,其它单词变成小写
_"""
函数说明:测试朴素贝叶斯分类器,使用朴素贝叶斯进行交叉验证
"""
def spamTest():
docList=[]; classList = []; fullText =[]
for i in list(range(1,26)): _#__遍历__25__个__txt__文件
_wordList = textParse(open('email/spam/%d.txt' % i,encoding='ISO-8859-1').read()) _#__读取每个垃圾邮件,并字符串转换成字符串列表
_docList.append(wordList)
fullText.extend(wordList)
classList.append(1) _#__标记垃圾邮件,__1__表示垃圾文件
_wordList = textParse(open('email/ham/%d.txt' % i,encoding='ISO-8859-1').read()) _#__读取每个非垃圾邮件,并字符串转换成字符串列表
_docList.append(wordList)
fullText.extend(wordList)
classList.append(0) _#__标记正常邮件,__0__表示正常文件
_vocabList = createVocabList(docList) _#__创建词汇表,不重复
__# print(len(vocabList))
_trainingSet = list(range(50)); testSet=[] _#__创建存储训练集的索引值的列表和测试集的索引值的列表
_for i in list(range(10)): _#从__50__个邮件中,随机挑选出__40__个作为训练集,10__个做测试集
_randIndex = int(np.random.uniform(0,len(trainingSet))) _#__随机选取索索引值
_testSet.append(trainingSet[randIndex]) _#__添加测试集的索引值
_del(trainingSet[randIndex]) _#__在训练集列表中删除添加到测试集的索引值
_trainMat=[]; trainClasses = [] _#__创建训练集矩阵和训练集类别标签系向量
_for docIndex in trainingSet: _#__遍历训练集
_trainMat.append(bagOfWords2VecMN(vocabList, docList[docIndex])) _#__将生成的词集模型添加到训练矩阵中
_trainClasses.append(classList[docIndex]) _#__将类别添加到训练集类别标签系向量中
_p0V,p1V,pSpam = trainNB0(np.array(trainMat),np.array(trainClasses)) _#__训练朴素贝叶斯模型
_errorCount = 0 _#__错误分类计数
_for docIndex in testSet: _#__遍历测试集
_wordVector = bagOfWords2VecMN(vocabList, docList[docIndex]) _#__测试集的词集模型
_if classifyNB(np.array(wordVector),p0V,p1V,pSpam) != classList[docIndex]: _#__如果分类错误
_errorCount += 1 # _错误计数加__1
_print ("分类错误的测试集:",docList[docIndex])
print ('错误率: ',float(errorCount)/len(testSet))
_#return vocabList,fullText
_if __name__ == '__main__':
spamTest()
文本分类实验代码及注释:
from numpy import *
"""
loadDataSet函数说明: 创建一些实验样本
Returns:
postingList - 原始的词条列表
classVec - 类别标签向量
"""
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] #1 代表侮辱性文字, 0 代表正常言论
return postingList,classVec
"""
createVocabList函数说明:将切分的实验样本词条整理成不重复的词条列表
Parameters:
dataSet - 整理的样本数据集
Returns:
vocabSet - 返回不重复的词条列表,也就是词汇表
"""
def createVocabList(dataSet): #创建一个包含在所有文档中的不重复词的列表
vocabSet = set([]) #创建一个空集
for document in dataSet:
vocabSet = vocabSet | set(document) # “ |”代表创建两个集合的并集
return list(vocabSet)
"""
函数说明:根据vocabList词汇表,构建词袋模型
Parameters:
vocabList - createVocabList返回的列表
inputSet - 切分的词条列表
Returns:
returnVec - 文档向量,词袋模型
"""
def bagOfWords2Vec(vocabList, inputSet): #创建一个其中所含元素为0的向量
returnVec = [0]*len(vocabList)
for word in inputSet:
if word in vocabList:
returnVec[vocabList.index(word)] += 1
return returnVec
"""
trainNB0函数说明:朴素贝叶斯分类器训练函数
Parameters:
trainMatrix - 训练文档矩阵,即bagOfWords2Vec返回的returnVec构成的矩阵
trainCategory - 训练类别标签向量,即loadDataSet返回的classVec
Returns:
p0Vect - 正常邮件类的条件概率数组
p1Vect - 垃圾邮件类的条件概率数组
pAbusive - 文档属于垃圾邮件类的概率
"""
def trainNB0(trainMatrix,trainCategory):#输入参数为文档矩阵trainMatrix,和每篇文档类别标签所构成的向量trainCategory
numTrainDocs = len(trainMatrix)
numWords = len(trainMatrix[0])
pAbusive = sum(trainCategory)/float(numTrainDocs)
p0Num = zeros(numWords); p1Num = zeros(numWords) #初始化概率
p0Denom = 0.0; p1Denom = 0.0
#p0Num = ones(numWords); p1Num = ones(numWords)
#p0Denom = 2.0; p1Denom = 2.0
for i in range(numTrainDocs):
if trainCategory[i] == 1:
p1Num += trainMatrix[i]
p1Denom += sum(trainMatrix[i])
else:
p0Num += trainMatrix[i]
p0Denom += sum(trainMatrix[i])
p1Vect = p1Num/p1Denom #change to log()
p0Vect = p0Num/p0Denom #change to log()
#p1Vect = log(p1Num/p1Denom)
#p0Vect = log(p0Num/p0Denom)
return p0Vect,p1Vect,pAbusive
"""
classifyNB函数说明:朴素贝叶斯分类器分类函数
Parameters:
vec2Classify - 待分类的词条数组
p0Vec - 正常邮件类的条件概率数组
p1Vec - 垃圾邮件类的条件概率数组
pClass1 - 文档属于垃圾邮件的概率
Returns:
0 - 属于正常邮件类
1 - 属于垃圾邮件类
"""
def classifyNB(vec2Classify, p0Vec, p1Vec, pClass1):
p1 = sum(vec2Classify * p1Vec) + log(pClass1)
p0 = sum(vec2Classify * p0Vec) + log(1.0 - pClass1) #2分类问题可以用1.0-pClass1,多分类需要修改
if p1 > p0:
return 1
else:
return 0
"""
函数说明:测试朴素贝叶斯分类器,使用朴素贝叶斯进行交叉验证
0 - 属于正常邮件类
1 - 属于垃圾邮件类
"""
def testingNB():
listOPosts, listClasses = loadDataSet()
myVocabList = createVocabList(listOPosts)
trainMat = []
for postinDoc in listOPosts:
trainMat.append(bagOfWords2Vec(myVocabList, postinDoc))
p0V, p1V, pAb = trainNB0(array(trainMat), array(listClasses))
testEntry = ['love', 'my', 'dalmation']
thisDoc = array(bagOfWords2Vec(myVocabList, testEntry))
print(testEntry, 'classified as: ', classifyNB(thisDoc, p0V, p1V, pAb))
testEntry = ['stupid', 'garbage']
thisDoc = array(bagOfWords2Vec(myVocabList, testEntry))
print(testEntry, 'classified as: ', classifyNB(thisDoc, p0V, p1V, pAb))
if __name__ == '__main__':
testingNB()