中国地质大学(武汉)信息工程学院-《大数据技术与应用》课程实习报告2015年秋-1-Lab_1基于朴素贝叶斯的垃圾邮件检测一、实习目的与要求1、结合实际应用理解分类的分类过程;2、深入理解特征提取、数据处理、训练、测试、分类评估等过程;3、理论结合实践,采用朴素贝叶斯方法实现垃圾邮件的检测;4、通过进一步查阅文献,了解相关研究方向的最新研究进展。二、实习题目利用基于概率论的分类方法——朴素贝叶斯方法,实现垃圾邮件的检测。【实验数据】50封包含纯文本内容的电子邮件,其中50%SPAM,50%HAM。【分类过程描述】(1)数据预处理a)获取原始数据:数据集放在email文件夹中,该文件夹又包含两个子文件夹,分别是spam-bad与ham-good,程序与该email文件夹放在同一个目录里。foriinrange(1,26):wordList=textParse(open('email/spam-bad/%d.txt'%i).read())docList.append(wordList)fullText.extend(wordList)classList.append(1)wordList=textParse(open('email/ham-good/%d.txt'%i).read())docList.append(wordList)fullText.extend(wordList)classList.append(0)b)查看数据样本:数据已被读入wordList中,用classList标记邮件来源于spam-bad还是ham-good,以便于最后的随机选取训练样本与测试样本及正确率检测。c)编写数据过滤程序:1201520612娄建生实习一基于朴素贝叶斯的垃圾邮件检测-2-对于一个文本字符串,可以使用python的split()方法将其切分,但是标点符号也被当成了词的一部分,可以使用正则表示式来切分句子,其中分隔符是除单词、数字外的任意字符串。但是里面的空字符串需要去掉,可以计算每个字符串的长度,只返回长度大于0的字符串。最后将所有字符串转换为小写:deftextParse(bigString):importrelistOfTokens=re.split(r'\W*',bigString)return[tok.lower()fortokinlistOfTokensiflen(tok)2]d)将文本转换为标记向量,以便进行概率计算与处理:defbagOfWords2VecMN(vocabList,inputSet):returnVec=[0]*len(vocabList)forwordininputSet:ifwordinvocabList:returnVec[vocabList.index(word)]+=1returnreturnVece)分离训练样本与测试样本:构建一个测试集与一个训练集,两个集合中的邮件都是随机选出的。本例中共有50封电子邮件,并不是很多,其中的10封电子邮件被随机选择为测试集。分类器所需要的概率计算只利用训练集中的文档来完成。python变量trainingSet是一个整数列表,其中的值从0到49。接下来,随机选择其中10个文件,选择出的数字所对应的文档被添加到测试集,同时也将其从训练集中剔除:trainingSet=range(50);testSet=[]foriinrange(10):randIndex=int(random.uniform(0,len(trainingSet)))testSet.append(trainingSet[randIndex])del(trainingSet[randIndex])(2)模型训练a)训练:使用算法对可用训练数据生产训练模型:trainMat=[];trainClasses=[]fordocIndexintrainingSet:trainMat.append(bagOfWords2VecMN(vocabList,docList[docIndex]))trainClasses.append(classList[docIndex])p0V,p1V,pSpam=trainNB0(array(trainMat),array(trainClasses))b)测试:如果邮件分类错误,则错误数加1,最后给出总的错误百分比:errorCount=0fordocIndexintestSet:wordVector=bagOfWords2VecMN(vocabList,docList[docIndex])ifclassifyNB(array(wordVector),p0V,p1V,pSpam)!=classList[docIndex]:errorCount+=1printclassificationerror,docList[docIndex]print'theerrorrateis:',float(errorCount)/len(testSet)中国地质大学(武汉)信息工程学院-《大数据技术与应用》课程实习报告2015年秋-3-(3)分类结果评价函数会输出在10封随机选择的电子邮件上的分类错误率。既然这些电子邮件是随机选择的,所以每次的输出结果可能有些差别。如果发现错误的话,函数会输出错分文档的词表,这样就可以了解到底是哪篇文档发生了错误。如果想要更好地估计错误率,那么就应该将上述过程重复多次,比如说10次,然后求平均值。【源代码】#-*-coding:utf-8-*-fromnumpyimport*defcreateVocabList(dataSet):vocabSet=set([])fordocumentindataSet:vocabSet=vocabSet|set(document)returnlist(vocabSet)deftrainNB0(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.0foriinrange(numTrainDocs):iftrainCategory[i]==1:p1Num+=trainMatrix[i]p1Denom+=sum(trainMatrix[i])else:p0Num+=trainMatrix[i]p0Denom+=sum(trainMatrix[i])p1Vect=log(p1Num/p1Denom)p0Vect=log(p0Num/p0Denom)returnp0Vect,p1Vect,pAbusivedefclassifyNB(vec2Classify,p0Vec,p1Vec,pClass1):p1=sum(vec2Classify*p1Vec)+log(pClass1)p0=sum(vec2Classify*p0Vec)+log(1.0-pClass1)ifp1p0:return1else:return01201520612娄建生实习一基于朴素贝叶斯的垃圾邮件检测-4-defbagOfWords2VecMN(vocabList,inputSet):returnVec=[0]*len(vocabList)forwordininputSet:ifwordinvocabList:returnVec[vocabList.index(word)]+=1returnreturnVecdeftextParse(bigString):importrelistOfTokens=re.split(r'\W*',bigString)return[tok.lower()fortokinlistOfTokensiflen(tok)2]defspamTest():docList=[];classList=[];fullText=[]foriinrange(1,26):wordList=textParse(open('email/spam-bad/%d.txt'%i).read())docList.append(wordList)fullText.extend(wordList)classList.append(1)wordList=textParse(open('email/ham-good/%d.txt'%i).read())docList.append(wordList)fullText.extend(wordList)classList.append(0)vocabList=createVocabList(docList)trainingSet=range(50);testSet=[]foriinrange(10):randIndex=int(random.uniform(0,len(trainingSet)))testSet.append(trainingSet[randIndex])del(trainingSet[randIndex])trainMat=[];trainClasses=[]fordocIndexintrainingSet:trainMat.append(bagOfWords2VecMN(vocabList,docList[docIndex]))trainClasses.append(classList[docIndex])p0V,p1V,pSpam=trainNB0(array(trainMat),array(trainClasses))errorCount=0fordocIndexintestSet:wordVector=bagOfWords2VecMN(vocabList,docList[docIndex])ifclassifyNB(array(wordVector),p0V,p1V,pSpam)!=classList[docIndex]:errorCount+=1printclassificationerror,docList[docIndex]print'theerrorrateis:',float(errorCount)/len(testSet)spamTest()中国地质大学(武汉)信息工程学院-《大数据技术与应用》课程实习报告2015年秋-5-【改进设想】想要提高算法的分类精度,就要从分类器入手。在以后的学习中,尝试多种分类方法,比如SVM,决策树,神经网络,KNN方法等。比较分类效果,以提高算法精度。三、本次实习小结通过本次实习,收货很多。首先,对Python语言的运用起来更熟悉;其次,提高了自己的分析问题解决问题的能力;而且对朴素贝叶斯算法有了一定程度的掌握,为以后分类的学习提供了一个很好的基础。1201520612娄建生实习一基于朴素贝叶斯的垃圾邮件检测-6-=======================================================我的联系方式:电话:13429898573邮箱:13429898573@163.com请将以上报告在下周三(12月9日)前发至我的邮箱。